2013-08-23 7 views
20

Sono un novizio in Java. Ora sto studiando equals e == e ridefinizione di equals e toString.Come stampare l'indirizzo di un oggetto se si è ridefinito il metodo toString

Vorrei utilizzare sia il metodo toString che ho ridefinito sia il metodo predefinito ereditato dalla classe Object.

Non sono riuscito a utilizzare quel super modificatore per raggiungere tale metodo.

Questo è solo per scopi didattici. Quello che mi piacerebbe ottenere è più chiaro se si guarderanno i commenti nel mio codice.

Potresti aiutarmi qui?

Il mio codice è:

public class EqualTest{ 
    public static void main(String[] args){ 
     Employee alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15); 
      //System.out.super.println(alice1); 

     Employee alice2 = alice1; 
      //System.out.super.println(alice2); 

     Employee alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15); 
      //System.out.super.println(alice3); 

     System.out.println("alice1==alice2: " + (alice1==alice2)); 
     System.out.println("alice1 == alice3: " + (alice1==alice3)); 
     System.out.println("alice1.equals(alice3): " + alice1.equals(alice3)); 
    } 
} 

class Employee{ 
... 
    public String toString(){ 
     return getClass().getName() + "[name = " + name + 
      ", salary=" + salary + ", hireDay=" + hireDay + "]"; 
    } 

} 
+3

In primo luogo non si chiama ridefinizione è chiamato overriding –

+2

Ma l'implementazione di default non restituisce l'indirizzo dell'oggetto. Restituisce il nome della classe e il codice hash di quell'oggetto. Dalla documentazione di java.lang.Object: 'getClass(). GetName() +' @ '+ Integer.toHexString (hashCode())' – Matthias

+0

Bene, sì. Ma il codice hash è l'indirizzo. Guarda la documentazione di Object hashCode: questo viene in genere implementato convertendo l'indirizzo interno dell'oggetto in un numero intero, ma questa tecnica di implementazione non è richiesta dal linguaggio di programmazione JavaTM. Quindi, il codice hash è lo stesso numero esadecimale che rappresenta l'indirizzo. Ma è stato convertito in decimale. – Kifsif

risposta

39

A rigor di termini, non è possibile stampare l'indirizzo di un oggetto in puro Java. Il numero che assomiglia a un indirizzo oggetto nella stringa prodotta da Object.toString() è "codice hash identità" dell'oggetto. Si può o non può essere correlato al indirizzo attuale dell'oggetto:

  • Le specifiche non dicono come il numero di identificazione codice hash viene calcolato. È volutamente lasciato non specificato.

  • Poiché il numero è un codice hash, è impossibile cambiare. Pertanto, anche se è (in genere) correlato a un indirizzo oggetto, questo sarà l'indirizzo dell'oggetto al momento dell'accesso per la prima volta all'hashcode.Questo potrebbe essere diverso dal suo attuale indirizzo, e lo sarà diverso se il GC ha spostato l'oggetto dal primo momento in cui è stato osservato l'hashcode dell'identità dell'oggetto.

  • Su una JVM a 64 bit (con una grande dimensione heap abbastanza/non si utilizza compressi oops) indirizzi non si inseriscono in un numero di codice hash identità che viene restituito come un int.

In ogni caso, il modo per ottenere questo numero è quello di chiamare System.identityHashCode(obj).


Se si vuole veramente indirizzo attuale di un oggetto, è possibile ottenere utilizzando JNI e un metodo nativo (e un po 'di astrazione rottura), o utilizzando metodi della classe Unsafe. Ma attenzione che entrambi questi approcci sono non portabili ... e che gli indirizzi degli oggetti che ti danno sono suscettibili di "rompersi" quando il GC viene eseguito.

+0

Per favore, guarda qui: http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode() I proprio non riesco a capire perché tutti dicono che non è l'indirizzo. Se è intero, non significa che non è l'indirizzo. L'indirizzo è convertito in int. – Kifsif

+2

@ Kifsif - Questo non dice che è un indirizzo. –

+0

Ovviamente no. Dice: "Questo è tipicamente implementato convertendo l'indirizzo interno dell'oggetto in un numero intero, ma questa tecnica di implementazione non è richiesta dal linguaggio di programmazione JavaTM". Tipicamente implementato implica che in Oracle JDK è fatto in questo modo. Ho sbagliato? Anche se lo sono, nessuno sa come viene costruito Oracle JDK in quanto è un software chiuso. – Kifsif

0

È possibile chiamare il metodo super() per eseguire il metodo della superclasse corrispondente.

class Employee{ 
... 
    public String toString(){ 
     String s = super.toString(); 
     return getClass().getName() + "[name = " + name + 
      ", salary=" + salary + ", hireDay=" + hireDay + "]" + s; 
    } 

toString() nella classe Object è la seguente

public String toString() { 
    return getClass().getName() + "@" + Integer.toHexString(hashCode()); 
} 
7

Se si desidera ottenere il tipo predefinito di comportamento toString(), è possibile utilizzare il metodo System.identityHashCode(). Predefinito toString() sarà quindi simile a questa:

public String toString(Object o) { 
    return o.getClass().getName() + "@" + 
      Integer.toHexString(System.identityHashCode(o)); 
} 
0

è possibile creare un altro metodo all'interno della vostra classe Impiegato di utilizzare il metodo super-toString.

Vedere esempio:

public class Employee { 
    public String toString() { 
     return "MyToStringMethod"; 
    } 

    public String superToString() { 
     return super.toString(); 
    } 

    public static void main(String[] args) { 
     Employee b = new Employee(); 
     System.out.println(b); 
     System.out.println(b.superToString()); 
    } 
} 

o combinare entrambi in un metodo:

public class Employee { 
    public String toString() { 
     return super.toString() + " MyToStringMethod"; 
    } 

    public static void main(String[] args) { 
     Employee b = new Employee(); 
     System.out.println(b); 
    } 
} 
Problemi correlati