2008-08-19 10 views
19

Ich dachte immer, dass die .equals() -Methode in Java überschrieben werden sollte, um für die von Ihnen erstellte Klasse spezifisch zu sein. Mit anderen Worten, nach Äquivalenz von zwei verschiedenen Instanzen anstatt zwei Referenzen auf dieselbe Instanz zu suchen. Ich habe jedoch andere Programmierer kennengelernt, die meinen, dass das Standardobjektverhalten in Ruhe gelassen werden sollte und eine neue Methode zum Testen der Äquivalenz zweier Objekte der gleichen Klasse erstellt wurde.Überschreiben der Methode equals im Vergleich zum Erstellen einer neuen Methode

Was ist das Argument für und gegen das Überschreiben der equals-Methode?

Antwort

19

die Gleichen Aufschalten Methode notwendig ist, wenn man Gleichwertigkeit testen wollen in Standardbibliotheksklassen (z. B. um sicherzustellen, dass ein java.util.Set eindeutige Elemente enthält oder Objekte als Schlüssel in java.util.Map-Objekten verwendet).

Hinweis: Wenn Sie equals überschreiben, müssen Sie sicherstellen, dass Sie den API-Vertrag gemäß der Beschreibung in der Dokumentation einhalten. Zum Beispiel stellen Sie sicher, auch Object.hashCode außer Kraft setzen:

Wenn zwei Objekte gleich sind nach der equals (Object) -Methode, dann auf jedem den beiden Objekten die hashCode-Methode aufrufen müssen die gleiche ganzzahlige Ergebnis produzieren .

EDIT: Ich habe nicht schreibe dies als eine vollständige Antwort zu diesem Thema, so werde ich Fredrik Kalseth Aussage Echo, dass übergeordnete Arbeiten für immutable objects am besten entspricht. Um die API für Map zu zitieren:

Hinweis: große Sorgfalt muss ausgeübt werden, wenn veränderbare Objekte als Kartenschlüssel verwendet werden. Das Verhalten einer Karte ist nicht angegeben, wenn der Wert eines Objekts in einer Weise geändert wird, dass Vergleiche wirkt sich gleich, während das Objekt ein Schlüssel in der Karte ist.

+2

Das effektive Java (Josh Bloch; 1. Aufl.) Kapitel über java.lang.Object Methoden: http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf – McDowell

0

Die Equals-Methode soll Referenzen vergleichen. Es sollte also nicht überschrieben werden, um sein Verhalten zu ändern.

Sie sollten eine neue Methode erstellen für Gleichwertigkeit in verschiedenen Instanzen zu testen, ob Sie müssen (oder die CompareTo Methode in einigen .NET-Klassen verwenden)

0

Sie sollten nur müssen die equals() Methode außer Kraft zu setzen, wenn Sie ein bestimmtes Verhalten wollen, wenn Objekte zu sortierten Datenstrukturen (SortedSet etc.)

Hinzufügen Wenn Sie das tun Sie auch hashCode() außer Kraft setzen sollte.

Eine vollständige Erklärung finden Sie unter here.

8

Ich würde empfehlen, eine Kopie von Effective Java und Lesen durch Punkt 7, gehorcht der equals contract. Sie müssen vorsichtig sein, wenn Sie Gleichheitszeichen für änderbare Objekte überschreiben, da viele Sammlungen wie Maps und Sets Gleichheit verwenden, um Äquivalenz zu bestimmen, und wenn ein in einer Sammlung enthaltenes Objekt mutiert, kann dies zu unerwarteten Ergebnissen führen. Brian Goetz hat auch eine ziemlich gute overview of implementing equals and hashCode.

4

Sie sollten "nie" überschreiben gleich & getHashCode für veränderbare Objekte - dies gilt für .net und Java beide. Wenn Sie dies tun, und verwenden Sie ein solches Objekt als Schlüssel in f.ex ein Wörterbuch und dann Änderung dieses Objekt, werden Sie in Schwierigkeiten geraten, weil das Wörterbuch auf den Hashcode angewiesen ist, um das Objekt zu finden.

Hier ist ein guter Artikel zum Thema: http://weblogs.asp.net/bleroy/archive/2004/12/15/316601.aspx

0

Um ehrlich zu sein, in Java ist es nicht wirklich ein Argument gegen zwingende entspricht. Wenn Sie Instanzen auf Gleichheit vergleichen müssen, dann tun Sie das.

Wie oben erwähnt, müssen Sie mit hashCode, und in ähnlicher Weise bewusst Vertrag sein, beobachten rund um die Comparable Schnittstelle für die gotchas aus - in fast allen Situationen Sie die natürliche Ordnung wollen wie Vergleichbar definiert seine im Einklang mit equals (siehe BigDecimal api doc für das kanonische Gegenbeispiel)

eine neue Methode für die Erstellung von Gleichheit entscheiden, ganz abgesehen davon, nicht mit den vorhandenen Bibliotheksklassen arbeitet, in krassen von Java-Konvention etwas.

2

@ David Schlosnagle mentions erwähnt Josh Blochs Effective Java - das ist ein ist für alle Java-Entwickler-muss lesen.

Es gibt ein verwandtes Problem: Für unveränderbare Wertobjekte sollten Sie auch das Überschreiben von compare_to in Betracht ziehen. Die Standardformulierung für wenn sie unterscheiden sich in der Comparable API:

Es ist in der Regel der Fall, aber nicht unbedingt erforderlich, dass (vergleiche (x, y) == 0) == (x.equals (y)) . Im Allgemeinen sollte jeder Vergleicher, der gegen diese Bedingung verstößt, diese Tatsache deutlich angeben. Die empfohlene Sprache ist "Hinweis: Dieser Komparator führt zu Ordnungen, die nicht mit Gleichem übereinstimmen."

Verwandte Themen