2010-11-01 20 views
37

Sto lavorando su un problema di esempio di metodo hashCode e equals over-ridding ma ricevendo un errore: "Nessuna istanza di inclusione di tipo CustomHashCodeExample è accessibile. Deve qualificare l'allocazione con un'istanza allegata di tipo CustomHashCodeExample (egxnew A() dove x è un'istanza di CustomHashCodeExample). " Ho scritto una classe interna HashPerson e sto ricevendo questo errore quando sto provando a creare un'istanza di questa classe interna in un altro metodo chiamato testHashCodeOverride().Classe interna di istanziazione

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

Questo codice funziona bene, anche se non vedo classe interna statica o di un'istanza di classe esterna, confuso :(

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

Hai effettivamente letto il messaggio di errore? Ti dice ** esattamente ** cosa fare. Quando si crea un'istanza di una classe interna, deve essere qualificata con un'istanza della classe che la include. –

+0

Si dovrebbe davvero pulire la formattazione del codice di esempio e ridurlo all'essenziale. Nel suo stato attuale questo è praticamente illeggibile. – MForster

+0

È possibile semplificare il metodo 'hashCode' solo per' return name.hashCode(); ' –

risposta

106

Penso che si desidera dichiarare la classe HashPerson come static. Altrimenti può essere istanziata solo nel contesto della classe che contiene, sia in un metodo della classe che contiene o utilizzando il codice in questo modo:

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

In realtà, la mia regola empirica è quello di rendere ogni classe innestata statica , a meno che non abbia una ragione speciale per non farlo. Ciò è anche più efficiente, poiché le classi nidificate non statiche (chiamate classi interne ) contengono sempre un riferimento implicito all'oggetto contenitore.

+0

Grazie MForster, il posto in cui sono confuso, ho un programma di esempio che è scritto esattamente nello stesso modo in cui lo sto facendo qui e in quel codice, la classe interna non è statica e nessuno sta facendo un'istanza di contenere la classe. Mi manca qualcosa in quel codice? "Allegare il codice nella mia domanda" – t0mcat

+0

Stanno creando l'istanza all'interno di un metodo della classe contenente? – MForster

+0

Forse non sto leggendo il codice correttamente. Ho appena pubblicato il codice attuale. – t0mcat

7

è necessario o rendere la vostra classe interna statica, o fare riferimento ad esso attraverso un'istanza della classe esterna Molto probabilmente si desidera rendere statica la classe interna

I membri non statici di una classe (variabili, metodi, classi interne) sono per istanza della classe. quando accetto Se si analizzano membri non statici da un contesto statico (come un metodo statico come testHashCodeOverride), è necessario specificare un'istanza della classe di inclusione.

+0

Ciao oksayt , quindi nella maggior parte dei casi dovremmo rendere statica la classe interna? Qual è il modo preferito? Accesso tramite istanza di classe esterna o statica? – t0mcat

+0

Non utilizzare le classi interne per le API pubbliche. Le classi interne furono aggiunte per avere chiusure e classi anonime. –

+0

Per impostazione predefinita, le classi di livello superiore sono statiche, ma le classi interne non sono statiche. Se stai creando una classe interna solo per scopi di organizzazione del codice, è preferibile renderla 'static' e trattarla come una classe autonoma (con l'opzione di limitare la visibilità).Se hai bisogno che la classe interna abbia accesso ai membri non statici della sua classe di inclusione, devi renderla non statica. – oksayt

Problemi correlati