2010-11-01 41 views
37

Estoy trabajando en un problema de ejemplo de overherding hashCode e iguala el método pero obtengo un error: "No se puede acceder a ninguna instancia adjunta de tipo CustomHashCodeExample. Debe calificar la asignación con una instancia adjunta de tipo CustomHashCodeExample (egxnew) A() donde x es una instancia de CustomHashCodeExample). " Escribí una clase interna HashPerson y estoy obteniendo este error cuando intento crear una instancia de esta clase interna en otro método llamado testHashCodeOverride().Creando una instancia de la clase interna

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");   
} 

Este código funciona bien, aunque yo no veo clase interna estática o instancia de la clase externa, confundido :(

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; 

    } 
} 
+1

¿Leyó realmente el mensaje de error? Te dice ** exactamente ** qué hacer. Al crear instancias de una clase interna, debe calificarse con una instancia de la clase adjunta. –

+0

Debe realmente limpiar el formato del código de ejemplo y despojarlo de lo esencial. En su estado actual esto es prácticamente ilegible. – MForster

+0

Puede simplificar su método 'hashCode' para simplemente' return name.hashCode(); ' –

Respuesta

106

Creo que quiere declarar la clase HashPerson como static. De lo contrario, solamente puede representarse en el contexto de la clase que contiene, ya sea en un método de la clase que contiene o utilizando código como este:

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

En realidad, mi regla empírica es hacer cualquier clase anidada estática , a menos que tenga una razón especial para no hacerlo. Esto también es más eficiente, porque las clases anidadas no estáticas (llamadas clases internas) siempre contienen una referencia implícita al objeto contenedor.

+0

Gracias MForster, el lugar en el que estoy confundido, tengo un programa de ejemplo que está escrito exactamente de la misma manera que lo estoy haciendo aquí y en ese código, la clase interna no es estática y tampoco están creando una instancia de clase contenedora. ¿Me estoy perdiendo algo en ese código? "Adjuntar código en mi pregunta" – t0mcat

+0

¿Están creando la instancia dentro de un método de la clase contenedora? – MForster

+0

Quizás no estoy leyendo el código correctamente. Acabo de publicar el código real. – t0mcat

7

Necesitas o bien hacer que su clase interna estática, o referirse a ella a través de una instancia de la clase externa. Lo más probable es que solo desee hacer que su clase interna estética.

Los miembros no estáticos de una clase (variables, métodos, clases internas) son por instancia de la clase. cuando acce Al detectar miembros no estáticos de un contexto estático (como un método estático como testHashCodeOverride), debe especificar una instancia de la clase adjunta.

+0

Hola oksayt Entonces, ¿en la mayoría de los casos deberíamos hacer que la clase interna estética? ¿Cuál es la forma preferida? ¿Accediendo a través de una instancia de clase externa o estática? – t0mcat

+0

No use clases internas para API públicas. Las clases internas se agregaron para tener cierres y clases anónimas. –

+0

De forma predeterminada, las clases de nivel superior son estáticas, pero las clases internas no son estáticas. Si está creando una clase interna solo para fines de organización del código, es preferible hacerlo 'estático' y tratarlo como una clase independiente (con la opción de limitar la visibilidad).Si necesita que la clase interna tenga acceso a los miembros no estáticos de su clase envolvente, entonces debe hacerlo no estático. – oksayt

Cuestiones relacionadas