2013-04-19 16 views
23

Sto cercando di capire l'implementazione nativa del metodo hashCode(). Cosa restituisce esattamente questo metodo? È un indirizzo di memoria o è un valore casuale?Java Object.hashCode() - address o random()?

+4

Le fonti OpenJDK dovrebbero dire. Dubito che sia un indirizzo di memoria dato che il GC può spostare oggetti in memoria, probabilmente è una sorta di handle di oggetti interni. – millimoose

+0

Questo è un estratto di detto codice del 2008: http://blogs.tedneward.com/CommentView,guid,eca26c5e-307c-4b7c-931b-2eaf5b176e98.aspx – millimoose

+0

E direttamente dalla bocca del cavallo: http: // hg .openjdk.java.net/jdk7/hotspot/hotspot/file/9b0ca45cd756/src/share/vm/runtime/synchronizer.cpp Il codice ha lo stesso aspetto del post del blog. – millimoose

risposta

35

.hashCode() implementazione nativa dipende JVM.

E.g. HotSpot ha 6 implementazioni Object.hashCode(). È possibile scegliere utilizzando -XX:hashCode=n bandiera esecuzione JVM tramite linea di comando, dove n:

0 - Park-Miller RNG (default)
1 - f (indirizzo, global_statement)
2 - costante 1
3 - contatore seriale
4 - oggetto indirizzo
5 - Xorshift thread-local

+3

È anche interessante notare che poiché lo spazio per archiviare le cose nell'intestazione dell'oggetto è limitato, l'hashcode predefinito è solo [25 bit di larghezza] (https://stackoverflow.com/questions/26357186/what-is-in-java -object-header), non i 32 bit completi di un int. – Boann

20

Da the documentation:

Per quanto ragionevolmente possibile, il metodo hashCode definito dalla classe Object non ritorno interi distinti per oggetti distinti. (Questo è tipicamente implementato convertendo l'indirizzo interno dell'oggetto in numero intero, ma questa tecnica attuazione non è richiesta dal linguaggio programmazione Java TM.)

Così può essere correlato ad una memoria indirizzo, ma non deve essere - e sicuramente non dovresti dare per scontato che sia collegato alla memoria.

Nulla di ciò che si fa con un codice hash dovrebbe preoccuparsene affatto. I uniche cose che si dovrebbe dedurre da codici hash sono:

  • Se i codici hash di due oggetti sono gli stessi, hanno possono essere oggetti uguali
  • Se i codici hash di due oggetti sono diversi, essi non sono oggetti uguali (assumendo una corretta attuazione, sia sostituito o meno)
+0

Considerando GC, può l'hash codice è anche l'indirizzo di memoria, in primo luogo? Per l'uso nelle tabelle hash, non dovrebbe davvero cambiare in modo imprevedibile durante l'esecuzione. – millimoose

+5

@millimoose: Sicuramente non può essere l'indirizzo di memoria * corrente * di fronte a un GC di compattazione. Ma potrebbe essere "l'indirizzo al momento della prima chiamata, che viene poi ricordato per dopo" forse. Cerco di non preoccuparmi troppo :) –

+1

Passando al [vecchio estratto di codice che ho trovato] (http://blogs.tedneward.com/CommentView,guid,eca26c5e-307c-4b7c-931b-2eaf5b176e98.aspx), sicuramente * sembra * (nella misura in cui riesco a leggere la C piuttosto pelosa) come "un numero determinato una volta poi salvato". Con sei implementazioni disponibili, incluso l'indirizzo di memoria iniziale e un RNG. – millimoose

3

tua risposta sta here. Come menzionato nella documentazione:

Per quanto ragionevolmente pratico, il metodo hashCode definito dalla classe Object restituisce interi distinti per oggetti distinti. (Questo è tipicamente implementato convertendo l'indirizzo interno dell'oggetto in numero intero, ma questa tecnica attuazione non è richiesta dal linguaggio di programmazione JavaTM.)