2012-06-16 17 views
5

So che quando stiamo passando oggetti stiamo passando il suo riferimento come valore. Ma questo valore si ottiene sta usando il metodo hashcode() giusto (secondo i miei test è lo stesso)? Poiché hashcode() non è l'indirizzo di memoria e non è garantito il recupero di valori univoci per tutto il tempo, possono esserci strane cose come collisioni quando si passano oggetti?cosa succede veramente quando si passano oggetti in java?

(Supponendo hashcode() non è trovare un limite, vale a dire, restituisce lo stesso valore di System.identityHashCode())

Tre sono molti come questo domande, ma non riesco a trovare una risorsa rilevante che discuses ciò è che essere il valore passato e come lo hai preso?

MODIFICA: Ecco il mio test. Il valore predefinito toSting() utilizza lo hashCode() all'interno e lo converte in un valore esadecimale. Quindi, quando stiamo passando oggetti, è questo il valore che viene passato? O cosa fa java per tenere traccia di tutti gli oggetti (passati), quindi non ci saranno più riferimenti di collisione?

Object o = new Object(); 
System.out.println(o); 
System.out.println(o.toString()); //both prints same thing - [email protected] 

risposta

6

hashcode() non è coinvolto in alcun modo con la memoria di memoria interna di Java. È solo un metodo che dovrebbe restituire un valore unico che può rappresentare un oggetto.

Ora, è così come che un buon modo per ottenere un valore univoco per rappresentare un oggetto è utilizzare il suo indirizzo di memoria interno. Ed è quello che fa l'implementazione predefinita di hashcode(). Ma il fatto che hashcode()utilizza un indirizzo di memoria non non significa che hashcode()definisce l'indirizzo di memoria.

+0

Come dici tu se l'implementazione predefinita restituisce l'indirizzo di memoria, quindi non è un problema. Ma quello che ho visto è che è (funzione predefinita) non è garantito per restituire l'indirizzo di memoria. Ma di nuovo cosa succede quando ci sono più oggetti di 2^32 e hashcode() restituisce un intero che è 32 bit ?? – KillBill

+0

@ user601L 'hashcode()' non è assolutamente un metodo infallibile. Occasionalmente ci sono scontri. Ma troverà sempre qualche valore da restituire, indipendentemente dal fatto che usi o meno l'indirizzo di memoria per ottenerlo. Non dovresti davvero preoccupartene molto, solo sapere che le collisioni sono possibili nei casi limite. –

+0

@bohemian Grazie per aver corretto il mio grammer. Imaidiot. –

2

Ma questo valore che si ottiene sta usando il codice hash() metodo giusto (secondo i miei test è lo stesso)?

No.

Da JSL:

I valori di riferimento (spesso solo riferimenti) sono puntatori a questi oggetti e riferimento null speciale, che si riferisce ad alcun oggetto.

Leggi pagina da Harnessing Java

2

L'implementazione predefinita di codice hash per Object in Java è basata su l'indirizzo di memoria dell'oggetto, che è anche quello che il riferimento è.

Questo non significa che hashCode() viene chiamato per ottenere il riferimento. Questo non è quello che succede. La variabile di riferimento mantiene solo l'indirizzo di memoria dopo averlo ricevuto da un'istanza (new Whatever()). In effetti, è normale che le implementazioni di classe eseguano l'override di hashcode() per fare qualcosa di diverso.

+7

L'implementazione predefinita non restituisce l'indirizzo di memoria. Le macchine virtuali Java spostano di routine gli oggetti durante la fase di compattazione [compatta] (http://en.wikipedia.org/wiki/Mark-compact_algorithm), quindi l'uso dell'indirizzo di memoria renderebbe instabile "System.identityHashCode". –

1

In JavaObjects passano per mezzo di riferimento ogni volta che si passa un Object effettivamente si passa il riferimento oggetto originale. Un codice hash dipende dai valori dei campi associati a quell'oggetto. hashcode non ha nulla a che fare con il reale memory address., è molto raro che due oggetti con gli stessi valori abbiano hashcode diversi. Anche se si crea due oggetti diversi, ma hanno stessi valori il loro codice hash sarà stessa dipende sempre da quanto la funzione di hash è efficiente

+0

Sto parlando del codice hash predefinito() qui, o del codice system.identityhashcode(). – KillBill

2

v'è alcun obbligo o aspettativa che che hashCode() essere univoco. È non un metodo di identità.

Tuttavia, gran parte del JDK si aspetta che se a.equals(b), quindi a.hashCode() == b.hashCode().

Il contrario non è mai previsto; cioè se !a.equals(b) allora è non richiesto che a.hashCode() != b.hashCode(). Tuttavia, le prestazioni ne risentiranno se non si tratta del di solito. In altre parole, si prevede che lo hashCode() abbia poche collisioni.

L'implementazione predefinita hashCode() nella classe Object utilizza in genere l'indirizzo di memoria per generare il hashCode(), ma non ritorno l'indirizzo, né v'è alcun obbligo nelle specifiche di lingua per fare questo.

Problemi correlati