2012-06-16 6 views
5

Ich weiß, wenn wir Objekte übergeben, übergeben wir seine Referenz als Wert. Aber dieser Wert, den Sie erhalten, verwendet die Methode hashcode() (nach meinen Tests ist es das gleiche)? Da hashcode() ist nicht die Speicheradresse und nicht garantiert, um einzigartige Werte die ganze Zeit zu erhalten, kann es seltsame Dinge passieren wie Kollisionen beim Übergeben von Objekten?Was passiert wirklich, wenn Objekte in Java übergeben werden?

(Unter der Annahme, hashcode() nicht außer Kraft gesetzt werden, das heißt, es gibt den gleichen Wert wie System.identityHashCode())

Drei ähnliche Fragen sind viele, aber ich kann nicht eine relevante Ressource finden, die Diskusse, was dieser Wert Wesen übergeben und wie bekommen Sie es?

EDIT: Hier ist mein Test. Der Standardwert toSting() verwendet das hashCode() im Inneren und konvertiert es in einen Hexadezimalwert. Wenn wir also Objekte weitergeben, wird dieser Wert weitergegeben? Oder was macht Java, um alle Objekte im Auge zu behalten (wird übergeben), so wird es keine Referenzkollisionen geben?

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

Antwort

6

hashcode() ist in keiner Weise mit Java internen Speicher beteiligt. Es ist nur eine Methode, die einen eindeutigen Wert zurückgeben soll, der ein Objekt darstellen kann.

Jetzt ist es passiert einfach, dass eine nette Möglichkeit, einen eindeutigen Wert zu erhalten, um ein Objekt zu repräsentieren, ist die Verwendung seiner internen Speicheradresse. Und das ist es, was die Standardimplementierung von hashcode() tut. Aber die Tatsache, dass hashcode()verwendet eine Speicheradresse hat nicht bedeuten, dass hashcode()definiert die Speicheradresse.

+0

Wie Sie sagen, wenn die Standardimplementierung die Speicheradresse zurückgibt, ist es kein Problem. Aber was ich gesehen habe ist, dass es (Standardfunktion) nicht garantiert ist, die Speicheradresse zurückzugeben. Aber wieder was dann passiert, wenn es mehr Objekte als 2^32 gibt und hashcode() gibt eine ganze Zahl zurück, die 32 Bits ist ?? – KillBill

+0

@ user601L 'hashcode()' ist keineswegs eine narrensichere Methode. Es gibt gelegentlich Kollisionen. Aber es wird immer einen Wert finden, der zu Ihnen zurückkehrt, egal ob es seine Speicheradresse verwendet oder nicht. Sie sollten sich wirklich nicht viel Sorgen machen, nur wissen, dass Kollisionen in den Kantenfällen möglich sind. –

+0

@bohemian Danke für die Korrektur meiner Grammatik. Ich bin ein Idiot. –

2

Aber dieser Wert, den Sie erhalten, ist die Hash-Code() -Methode direkt mit (nach meinen Tests ist es das gleiche)?

Nr

Von JSL:

Die Referenzwerte (oft nur Referenzen) sind Zeiger auf diese Objekte und eine spezielle Nullreferenz, die auf kein Objekt verweist.

Lesen Sie diese Seite von Harnessing Java

2

Die Standardimplementierung von Hash-Code für Object in Java auf der Speicheradresse des Objekts basiert, das auch ist, was die Referenz.

Dies bedeutet nicht hashCode() wird aufgerufen, um die Referenz zu erhalten. Das ist nicht was passiert. Die Referenzvariable enthält nur die Speicheradresse, nachdem sie von einer Instanziierung abgerufen wurde (new Whatever()). Tatsächlich ist es bei Klassenimplementierungen üblich, Hashcode() zu überschreiben, um etwas anderes zu tun.

+7

Die Standardimplementierung gibt die Speicheradresse nicht zurück. Java VMs bewegen routinemäßig Objekte während der [compact] (http://en.wikipedia.org/wiki/Mark-compact_algorithm) -Phase der Garbage Collection, sodass die Verwendung der Speicheradresse "System.identityHashCode" instabil machen würde. –

1

In JavaObjects sind per Referenz bedeutet, wenn Sie jemals eine Object übergeben, übergeben Sie Original Object Referenz. Ein Hashcode hängt von den Feldwerten ab, die diesem Objekt zugeordnet sind. Hashcode hat nichts mit echten zu tun memory address. es ist sehr selten, dass zwei Objekte mit den gleichen Werten hashcode haben. Auch wenn Sie zwei verschiedene Objekte erstellen, aber dieselben Werte haben, ist ihr Hashcode immer gleich, je nachdem, wie effizient Ihre Hash-Funktion ist.

+0

Ich spreche hier über den Standard-Hashcode() oder den system.identityhashcode(). – KillBill

2

Es gibt keine Anforderung oder Erwartung, dass hashCode() eindeutig ist. Es ist nicht eine Identitätsmethode.

Allerdings erwartet viel JDK , dass, wenn a.equals(b), dann a.hashCode() == b.hashCode().

Das Gegenteil ist nie zu erwarten; d.h. wenn !a.equals(b) dann ist es nicht erforderlich, dass a.hashCode() != b.hashCode(). Allerdings wird die Leistung leiden, wenn dies nicht der Fall ist. Mit anderen Worten, es wird erwartet, dass hashCode() wenige Kollisionen hat.

Die Implementierung Standard hashCode() in der Object Klasse verwendet in der Regel die Speicheradresse zu die hashCode() erzeugen, aber es funktioniert nicht Rückkehr die Adresse, noch gibt es keine Notwendigkeit, in der Sprache spec dies zu tun ist.

Verwandte Themen