Die Identität von Objekten wird mit dem Operator ==
überprüft. Objekte gelten als identisch, und nur dann, wenn
ihre Referenzen gleich sind. In der folgenden Skizze zeigen die Objekte a2 und a3
auf die gleiche Referenz. Selbst wenn der wenn der Inhalt von a1, a2 und a3 gleich
ist, sind Sie nicht identisch, im Sinne der objektorientierten Programmierung.
Nachfolgendes Quelltextbeispiel zeigt eine mögliche Implementierung der
Skizze. Auf die Methoden boolean equals(Object o)
und
int hashCode()
der Klasse A wird im weiteren Verlauf eingegangen.
public class IdentityTest { public static void main(String[] args){ A a1 = new A(3), a2 = new A(3), a3 = a2; System.out.println(a1 == a2); System.out.println(a1 == a3); System.out.println(a2 == a3); } } class A{ private int i; public A(int i){ this.i = i; } public int hashCode(){ return 13+i; } public boolean equals(Object o){ if (!(o instanceof A)) return false; if (((A)o).i == i) return true; else return false; } }
Als Ergebnis des Programmablaufs wird folgendes auf der Systemausgabe ausgegeben:
false false true
Die Gleichheit von Objekten wird mit der Methode boolean equals(Object o)
überprüft. Die Methode boolean equals(Object o)
wird bereits
in der Klasse java.lang.Object
definiert und steht somit
in allen Objekten zur Verfügung. Die Methode boolean equals(Objkect o)
in
java.lang.Object
liefert allerdings nur im Falle der Objektidentität
den Wert true
. In allen anderen Fällen liefert
die Methode als Ergebnis den Wert false
.
Um nun mit der Objektgleichheit arbeiten zu können müssen die dazu
vorgesehenen Klassen die Methode boolean equals(Object o)
sinnvoll
überschreiben. Um der Objektgleichheit zu genügen ist es nicht immer
erforderlich, dass alle Attribute den selben Wert haben, vielmehr ist es erforderlich
im jeweiligen Kontext zu entscheiden, welche Attribute zum Vergleich herangezogen werden
müssen.
Wichtig ist beim überschreiben der Methode boolean equals(Object o)
darauf zu Achten ist, dass auch die Methode int hashCode()
(die ebenfalls
bereits in java.lang.Object
definiert ist) ebenfalls
zu überschreiben ist. Im Falle das die Methode boolean equals(Object o)
den Wert true
zurückgibt, muss auch die Methode int hashCode()
das selbe Ergebnis liefern.
Bei der Bildung des HashCodes sollten alle Elemente herangezogen werden, die
auch beim Vergleich mit boolean equals(Object o)
herangezogen
werden. Das nachfolgende Beispiel zeigt eine einfache Verwendung von
boolean equals(Object o)
und int hashCode()
.
Detailliertere Informationen sind unter
[1] zu finden.
public class Equality { private int i1, i2; private String s1, s2; public int hashCode(){ return 13*11+i1+i2+s1.hashCode(); } public boolean equals(Object o){ if (!(o instanceof Equality)) return false; Equality counterPart = (Equality) o; if (counterPart.i1 == i1 && counterPart.i2 == i2 && counterPart.s1.equals(s1)) return true; return false; } }
Bei der Übersetzung eines Programmes sammelt der Compiler alle Strings,
die mit gleichem Literal initialisiert werden, und weist Ihnen die selbe Referenz zu.
Daher ergibt der Vergleich von Stirngs, die mit gleichen Literalen gebildet
werden true
.
Dies ist ungefährlich, da Strings in Java unveränderlich (immutable)
sind.
public class StringIdentity { public static void main(String[] args){ String s1 = new String("Hello world"); String s2 = new String("Hello world"); String s3 = "Hello world"; String s4 = "Hello world"; System.out.println(s1 == s2); System.out.println(s3 == s4); System.out.println(s2 == s3); } }
Die Ausgabe des Programmes auf der Systemausgabe ist:
false true false
[1] Klaus Kreft & Angelika Langer
Hash-Code-Berechnung
http://www.angelikalanger.com/Articles/JavaSpektrum/03.HashCode/03.HashCode.html (Link nicht mehr verfügbar - 26.6.2012)
Eine detaillierte Beschreibung über den Zusammenhang von boolean equals(Object o)
und int hashCode()
.