2013-07-31 9 views
13

Ich bin auf der Suche nach dem Algorithmus Object.hashCode().Object.hashCode() Algorithmus

Dieser Code ist in Object.java nativ.

Ist das, weil

(a) der Code in assembly-- nie an allen

oder

in Java oder einer anderen HLL war

(b) es ist einfach nicht bekannt gegeben

? In jedem Fall suche ich nach dem Algorithmus (Pseudocode oder einige detaillierte Erklärungen) von "wie hashCode() berechnet wird" - welche Parameter in die Berechnung und die Berechnung einfließen selbst?

Bitte beachten Sie: Es ist die hashCode() of Object ich suche for-- nicht eine andere wie die von String oder Hashmap/table.

// ============================================ ==============================

die new Java docs - jdk 8 sagen jetzt

"The value returned by hashCode() is the object's hash code, which is the object's memory address in hexadecimal." 
+3

überprüfen können. Ich glaube, dass es nativ ist, da der HashCode des Objekts ein Speicheradressbezeichner ist, nicht tatsächlich ein Hash der Felder des Objekts . –

+0

Jemand muss die von Ihnen angegebenen Dokumente aktualisieren. Weil es völlig falsch ist. –

Antwort

0

Es ist weil es auf Low-Level-Details angewiesen ist, die nicht dem Java-Code ausgesetzt sind. Einige grundlegende Teile der Standardbibliothek (wie java.lang.Object) müssen in nativem Code implementiert werden.

Nebenbei finden Sie mindestens eine interesting article, die mehr über die HotSpot-Implementierung tut.

1

hashCode ist eine native Methode, was bedeutet, dass eine Systembibliothek intern aufgerufen wird. Dies liegt daran, dass Hashcode intern versucht, abhängig vom Objektspeicherplatz eine Zahl zu generieren. Dieser Code ist maschinenabhängig und wahrscheinlich in C geschrieben

Aber wenn Sie wirklich interessiert sind, den nativen Code zu sehen, dann ist dies wie folgt vor:

http://hg.openjdk.java.net/jdk7/jdk7-gate/jdk/file/e947a98ea3c1/src/share/native/java/

+0

Nun, das ist die Sache-- ist Objektspeicherort der einzige Parameter in HashCode() Berechnung gehen? Wie ist es gemacht - auf den unteren Bits der Adresse vielleicht? – Roam

8

Trotz der Javadoc, die algo darf nur die Adresse als Eingabe. Das bedeutet, dass neue Objekte zwar dieselbe Adresse im Eden-Space verwenden, sie aber nicht denselben HashCode haben.

Es gibt eine Reihe von Algos, die möglicherweise verwendet werden und nicht alle die Adresse verwenden.

Hinweis: Der HashCode() ist 31-Bit.

BTW Sie können es mit Unsafe.putInt(object, 1, value) auf Hotspot setzen.

Set<Integer> ints = new LinkedHashSet<>(); 
int negative = 0, nonneg = 0; 
for (int i = 0; i < 100; i++) { 
    System.gc(); 
    for (int j = 0; j < 100; j++) { 
     int h = new Object().hashCode(); 
     ints.add(h); 
     if (h < 0) negative++; 
     else nonneg++; 
    } 
} 
System.out.println("unique: " + ints.size() + " negative: " + negative + " non-neg: " + nonneg); 

druckt

unique: 10000 negative: 0 non-neg: 10000 

Unsafe

Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); 
theUnsafe.setAccessible(true); 
Unsafe unsafe = (Unsafe) theUnsafe.get(null); 

Object o = new Object(); 
System.out.println("From header " + Integer.toHexString(unsafe.getInt(o, 1L))); 
// sets the hashCode lazily 
System.out.println("o.hashCode() " + Integer.toHexString(o.hashCode())); 
// it's here now. 
System.out.println("after hashCode() From header " + Integer.toHexString(unsafe.getInt(o, 1L))); 
unsafe.putInt(o, 1L, 0x12345678); 
System.out.println("after change o.hashCode() " + Integer.toHexString(o.hashCode())); 

Drucke Mit

From header 0 
o.hashCode() 2260e277 
after hashCode() From header 2260e277 
after change o.hashCode() 12345678 
+1

"hashCode() verwendet nur die Adresse des Objekts" wäre konsistent mit den Spezifikationen unter http://www.docjar.com/docs/api/java/lang/Object.html#hashCode. aber dann sagst du "obwohl neue Objekte die gleiche Adresse verwenden, haben sie nicht den gleichen HashCode". Wie ist dann diese Krawatte gebrochen? ein anderer Speicherort als die Referenzadresse des Objekts (wie die eines Mitglieds, die Endadresse/Menge des Speichers, einige Sachen auf dem Zeitstempel ...?) – Roam

+0

obwohl erfüllt "selbe HashCode für das gleiche Objekt bei jedem Aufruf von HashCode() innerhalb einer Ausführung ", fühlt sich die Adresse des Objekts für diese Berechnung nicht so richtig an - zu konsistent mit dem Speicherraum, nicht so stark bezüglich der Zufälligkeit des Hashcodes. – Roam

+1

wäre es eine unveränderliche "handle" Kennung, die für die Lebensdauer des Objekts konstant bleiben würde. Höchstwahrscheinlich VM-Implementierung abhängig und wird wahrscheinlich keine Beziehung zur Speicheradresse haben, da aufgrund von GC-Operationen alle Objekte in Java im physischen Speicher verlagern können. – peterk

11

india hashCode Methode Implementierung auf dem JVM abhängt. In HotSpot gibt es eine Zufallszahl zurück, die Sie in der source code (Funktion get_next_hash)

+0

Thx für den interessanten Link. – Roam