web-dev-qa-db-fra.com

Instanciation de la classe intérieure

Je travaille sur un exemple de problème de surcharge de hashCode et de méthode égale mais j'obtiens une erreur: "Aucune instance de type CustomHashCodeExample n'est accessible. Doit qualifier l'allocation avec une instance de type CustomHashCodeExample (egxnew A() où x est une instance de CustomHashCodeExample). "J'ai écrit une classe interne HashPerson et j'obtiens cette erreur lorsque j'essaie d'instancier cette classe interne dans une autre méthode appelée testHashCodeOverride () .

public static void testHashCodeOverride(){   
    System.out.println("\nTest HashCode Override Method");
    System.out.println("==================================\n");

    HashPerson william = new HashPerson("willy");
    HashPerson bill = new HashPerson("willy");          
}

Ce code fonctionne bien, même si je ne vois pas de classe interne statique ou d'instanciation de classe externe, confus :(

public class HashCodeExample {

    public static void testHashCodeOverride() {

        HashPerson william = new HashPerson("Willy");
        HashPerson bill = new HashPerson("Willy");
        System.out.println("Hash code for william  = " + william.hashCode());
        System.out.println("Hash code for bill     = " + bill.hashCode());

        HashMap table = new HashMap();
        table.put(william, "Silly");

        if (table.containsKey(william)) {
            System.out.println(table.get(william));
        } else {
            System.out.println("Key " + william + " not found");
        }

        if (table.containsKey(bill)) {
            System.out.println(table.get(bill));
        } else {
            System.out.println("Key " + bill + " not found");
        }


    }

    class HashPerson {
        private static final int HASH_PRIME = 1000003;

        public HashPerson(String name) {
            this.name = name;
        }

        public String toString() {
            return name;
        }

        public boolean equals(Object rhs) {
            if (this == rhs)
                return true;

            // make sure they are the same class
            if (rhs == null || rhs.getClass() != getClass())
                return false;

            // ok, they are the same class. Cast rhs to HashPerson
            HashPerson other = (HashPerson) rhs;

            // our test for equality simply checks the name field
            if (!name.equals(other.name)) {
                return false;
            }

            // if we get this far, they are equal
            return true;
        }
        public int hashCode() {
            int result = 0;
            result = HASH_PRIME * result + name.hashCode();
            return result;
        }
        private String name;

    }
}
45
t0mcat

Je pense que vous voulez déclarer la classe HashPerson comme static. Sinon, il ne peut être instancié que dans le contexte de la classe conteneur, soit dans une méthode de la classe conteneur, soit en utilisant un code comme celui-ci:

ContainingClass container = new ContainingClass();
HashPerson william = container.new HashPerson("willy");

En fait, ma règle générale est de rendre statique toute classe imbriquée, sauf si j'ai une raison spéciale de ne pas le faire. Ceci est également plus efficace, car les classes imbriquées non statiques (appelées classes internes) contiennent toujours une référence implicite à l'objet conteneur.

127
MForster

Vous devez soit rendre votre classe interne statique, soit vous y référer via une instance de la classe externe. Il est fort probable que vous souhaitiez simplement rendre statique votre classe interne.

Les membres non statiques d'une classe (variables, méthodes, classes internes) sont par instance de la classe. Par conséquent, lorsque vous accédez à des membres non statiques à partir d'un contexte statique (comme une méthode statique comme testHashCodeOverride), vous devez spécifier une instance de la classe englobante.

8
oksayt