Überschreiben der equals-Methode
newbie-Frage hier:
So, in meinen Uni-Hausaufgaben muss ich das überschreiben der object-Klasse equals-Methode für eine neue Klasse von mir erstellt.
Die neue Klasse "Produkt" jedes Produkt hat ein Attribut "id" ist einzigartig. Also das ist, wie ich Overrided:
@Override
public boolean equals(Object obj) {
final Product other = (Product) obj;
if (id != other.id)
return false;
return true;
}
Die Sache ist, dass dies zu tun ist 1,5 von 10 Punkten und es machte mich suspicius, einfach sein. So begann ich zu suchen und fand ich Dinge wie:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Product other = (Product) obj;
if (id != other.id)
return false;
return true;
}
Die keinen Sinn ergeben für mich überhaupt, weil ich denke, dass die letzten wenn überprüfen Sie alle anderen ifs Einschränkungen. Was denken Sie?Was ist der bessere Weg, um diese Methode Überschreiben?
Dank!
Der Vertrag für gleich sagt, dass alle Objekte, die gleich sind, müssen den gleichen hashCode. Wenn Sie also überschreiben equals() überschreiben muss hashCode().
InformationsquelleAutor Iñaki | 2011-06-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dem zweiten Stück code ist besser:
x.equals(x)
, die nicht notwendig für Korrektheit, sondern ist eine hilfreiche Optimierungx.equals(null)
statt zu werfenNullPointerException
ClassCastException
was würde dir (z.B.x.equals("foo")
)obj.equals(x)
könnte, ruft eine andere Methode, die zu einem anderen Ergebnis.Es hängt davon ab, was du damit meinst "arbeiten". Es wird nicht behandeln, eine Instanz von Produkt als gleich eine Instanz der Unterklasse, Nein - aber ich glaube nicht, dass das kaputt ist, ist es einfach ein Verhalten, das muss dokumentiert werden.
ein.equals(b) immer false zurück wenn ein.getClass() == Product.class, b instanceof einige Unterklasse von Produkt -, und a und b haben die gleichen internen Zustand. So ist die equals () - Beziehung ist nicht symmetrisch. Dies verstößt gegen java.lang.Objekt-Vertrag.
Es wird nur asymmetrisch sein, wenn
b.equals(a)
gibt true zurück,... und es wäre nicht, wenn es aufgerufensuper.equals(a)
was es sollte. Ohne dieser Prüfunga.equals(b)
wird nur prüfen, fürid
so könnte es true " zurück, währendb.equals(a)
würde false zurückgeben, daa
ist nicht eine Instanz der gleichen Unterklasse vonProduct
oder eine Unterklasse der Unterklasse. Der AufrufgetClass()
ist genau dort zu Hilfe Symmetrie.Wenn man eine abstrakte Klasse repräsentiert eine unveränderliche Kombination von Werten (z.B. eine 2d-matrix von
double
), aber nicht Mandat ein bestimmtes Speicherformat, kann es Sinn machen, zu definieren, Gleichheit und hash-code in Bezug auf diese Werte. In einem solchen Fall, eineIdentityMatrix with
Größe " gleich drei vielleicht sinnvoll vergleichen Sie gleich einDiagonalMatrix
mitDiagonalValues
holding {1.0,1.0,1.0}.InformationsquelleAutor Jon Skeet
Die zweite version ist sicher, würde ich sagen, pedantisch. Ihre version, stattdessen Einführung eines
ClassCastException
weil Sie unter der Annahme, dass die Laufzeit-Typ der Variablenobj
ist der Typ Produkt. Das ist nicht wahr, das ist, warum Sie verwenden solltenthis.getClass() != obj.getClass()
(Sie dieses problem lösen könnte, auch mitinstanceof
Betreiber).Wenn ich
Bekomme ich auch eine exception, während ich bekommen sollte
false
.Darüber hinaus verwaltet die
product.equals(null)
problem, das sollte false zurückgeben, wie es inequals
Vertrag-Methode in der Dokumentation. Wenn Sie nicht kümmern, über dies und das tun Sie, man innen gleich:instanceof
in einer nicht-finalen Klasse gibt eine Symmetrie problem, wenn die Klasse als Unterklasse definiert.Ja, Sie sind richtig. Ich dachte über das überschreiben es wieder in einer Unterklasse..
InformationsquelleAutor Jack
Den gemeinsamen idiom verwendet beim überschreiben von equals() ist
In der zweiten version die du gepostet hast:
Optimierung nur, wenn die folgenden
Prüfungen sind zu viel teuer. Aber
ist dies nicht der Fall, so dass nur
redundanter code ist böse.
keine änderung an der Semantik der Methode equals().
(Zum Beispiel eine Klasse, die
bietet einigen Komfort-Methode, aber
keine zusätzlichen internen Zustand der
- Objekte.) Dies ist wegen der
Dritten, wenn().
InformationsquelleAutor ignis
Nummer 2 ist rechts von Effektive Java - für die sicherste Möglichkeit zum überschreiben der equals. 1 hat ein nullpointer, wenn das Objekt null ist, und es nicht so optimiert wie es sein könnte(muss nicht prüfen, ob obj eine Referenz auf sich selbst)
InformationsquelleAutor nsfyn55
Die Lösung von 'Joshua Bloch: Effective Java" ist (unter der Annahme, dass
Product
nicht eine Superklasse anderen alsObject
):Ihre erste Lösung leidet an zwei Nachteilen:
new Product(1).equals(null)
wirft eine NullpointerException, obwohl es angegeben wird false zurückgegeben, im Objekt.equals().new Product(1).equals(new Vector())
wirft eine classcastexception-Fehler, obwohl es angegeben wird false zurückgegeben, im Objekt.equals().Beide sind so zu beseitigen, dass die Instanz prüfen. Die
if (this == obj) return true;
ist oft nützlich für die Effizienz, aber wohl nicht notwendig, hier.Die zweite Lösung, die du gepostet hast, macht es schwierig, einen zu schreiben eine Unterklasse von Produkt mit guter Semantik. Wenn Sie eine Unterklasse
haben Sie
!new Product(4).equals(new SubProduct(4))
. Dies verstößt gegen Liskov ' s susbstitution Prinzip und ist oft vermutlich nicht so gut. Wenn Sie eine Finale Klassedie zweite-Lösungen ist die gleiche wie die oben genannten.
SubProduct
hat etwas mehr Stand und weitere überschreibungenequals
- dann, wenn Sieinstanceof
Sie am Ende mita.equals(b) != b.equals(a)
, die gegen dieObject
Vertrag. Über die genaue Klasse nicht immer, was Sie wollen in Bezug auf Liskov, aber es nicht ermöglicht das erstellen von Unterklassen, ohne dieObject
Vertrag. Geschlechter entlang einer Vererbungshierarchie ist im Grunde schmerzhaft 🙁Volle Zustimmung. Ich sorgfältig vermieden zu sagen "falsch" ist. Ich war nicht so vorsichtig Lesen der anderen Antworten, jedoch und verpasste Ihr noch mehr prägnante Gegenbeispiele.
InformationsquelleAutor Christoph Zenger