2 Stimmen

Überschreiben Sie equals und hashCode nur, um super.equals/hashCode aufzurufen, oder werfen Sie AssertionError?

Gibt es eine bewährte Praxis, wann Gleichheiten außer Kraft gesetzt werden sollten?

Sollte ich equals/hashCode außer Kraft setzen und einen AssertionError auslösen? Nur um sicher zu gehen, dass niemand das benutzt? (wie in dem Buch Effective Java empfohlen)

Sollte ich equals/hashCode außer Kraft setzen und nur super.equals/hashCode aufrufen, weil das Verhalten der Superklasse das gleiche ist? (FindBugs empfahl dies, weil ich ein Feld hinzugefügt habe)

Sind das wirklich bewährte Verfahren?

3voto

krock Punkte 27758

Fehler

Sie sollten keine Ausnahme von der equals o hashCode Methoden. Die Methoden "equals" und "hashCode" werden überall verwendet, wahlloses Auslösen von Ausnahmen könnte Ihnen später schaden.

AssertionError

Sie sollten niemals werfen AssertionError direkt. Die Website assert Anweisungen in eine beliebige Methode ist in Ordnung, da diese Anweisungen nicht ausgeführt werden, wenn Assertions ausgeschaltet sind.

Wann wird überstimmt?

Es kann nicht schaden, diese zu überschreiben und direkt an super.equals() wenn die Methode der Superklasse Object.equals .

Wenn es sich bei den beiden zu vergleichenden Objekten um unterschiedliche Typen handelt, können Sie in die Falle der Symmetriebrechung tappen, d. h. wenn x.equals(y) ist wahr, aber y.equals(x) falsch ist. Dies kann passieren, wenn y eine Unterklasse von x ist und die equals-Methode für y einen etwas anderen Vergleich durchführen kann. Sie können dies in Ihrer equals-Methode überprüfen, indem Sie if (getClass() != obj.getClass()) return false; .

Bewährte Praktiken

Leistungsfähiges Java ist hier eine großartige Ressource, insbesondere für die optimale Umsetzung der hashCode() Methode. Achten Sie darauf, dass Sie die Verträge der folgenden Organisationen lesen und berücksichtigen ist gleich y hashCode die in der Javadoc aufgeführt sind, und stellen Sie sicher, dass Sie, wenn Sie das eine überschreiben, auch das andere überschreiben. Die "Generate hashCode() and equals"-Funktion in Eclipse leistet gute Arbeit bei der Bereitstellung von Methoden, die Sie benötigen. Der folgende Code stammt aus der Javadoc von java.lang.Object .

entspricht dem Vertrag:

  • Sie ist reflexiv: Für jeden Referenzwert x, der nicht null ist, sollte x.equals(x) true zurückgeben.
  • Sie ist symmetrisch: Für beliebige Referenzwerte x und y, die nicht null sind, sollte x.equals(y) nur dann true zurückgeben, wenn y.equals(x) true zurückgibt.
  • Sie ist transitiv: Für beliebige Referenzwerte x, y und z, die nicht Null sind, sollte x.equals(y) true und y.equals(z) true ergeben, dann sollte x.equals(z) true ergeben.
  • Sie ist konsistent: Für beliebige Referenzwerte x und y, die nicht Null sind, geben mehrere Aufrufe von x.equals(y) konsistent true oder false zurück, vorausgesetzt, dass keine Informationen, die in Gleichheitsvergleichen der Objekte verwendet werden, geändert werden.
  • Für jeden Referenzwert x, der nicht null ist, sollte x.equals(null) false zurückgeben.

hashCode Contract:

  • Wenn die Methode hashCode während der Ausführung einer Java-Anwendung mehr als einmal für dasselbe Objekt aufgerufen wird, muss sie stets dieselbe ganze Zahl zurückgeben, vorausgesetzt, dass keine Informationen, die in Gleichheitsvergleichen für das Objekt verwendet werden, geändert werden. Diese Ganzzahl muss nicht von einer Ausführung einer Anwendung zu einer anderen Ausführung derselben Anwendung konsistent bleiben.
  • Wenn zwei Objekte gemäß der equals(Object)-Methode gleich sind, muss der Aufruf der hashCode-Methode für jedes der beiden Objekte das gleiche ganzzahlige Ergebnis liefern.
  • Es ist nicht erforderlich, dass zwei Objekte, die nach der equals(java.lang.Object)-Methode ungleich sind, beim Aufruf der hashCode-Methode für jedes der beiden Objekte unterschiedliche ganzzahlige Ergebnisse liefern müssen. Der Programmierer sollte sich jedoch darüber im Klaren sein, dass die Erzeugung unterschiedlicher Integer-Ergebnisse für ungleiche Objekte die Leistung von Hashtables verbessern kann.

2voto

Robert Diana Punkte 860

Wenn Sie zwei Objekte der gleichen Klasse vergleichen müssen, sollten Sie equals mit Ihrer eigenen Implementierung überschreiben. Wenn Sie equals überschreiben, sollten Sie auch eine Implementierung für hashCode bereitstellen. Es macht keinen Sinn, die Methoden zu überschreiben, nur um super aufzurufen, da dies das Standardverhalten ist. Ich würde die Methoden nicht überschreiben, um einen AssertionError auszulösen, da dies bedeutet, dass Sie die Objekte nie auf Gleichheit vergleichen oder in einer HashMap verwenden können. Es gibt auch andere Auswirkungen in den Collections-Klassen in diesem Fall.

0voto

Gareth Davis Punkte 27204

Übergeordnetes Recht equals y hashCode und rufen dann die Implementierungen der Superklassen mit super.equals() ist für mich nur eine sehr klare Art und Weise zu dokumentieren, dass Sie darüber nachgedacht haben und denken, dass die Implementierungen der Superklasse immer noch vollkommen gültig sind. Ich persönlich sehe kein Problem darin, dies einfach in der JavaDoc der Klasse zu dokumentieren und das Hinzufügen von equals & hashCode zu überspringen.

Das Auslösen von AssertionError ist ein wenig extrem und fällt nicht ganz unter das Prinzip der geringsten Überraschung. Wenn es wirklich ein Fehler ist, die Funktion equals() o hashCode() für Ihr Objekt verwenden UnSupportedOperationException stattdessen.

Wenn das Objekt, das Sie erweitern, Gleichheit unterstützt, wäre es eine gute Idee, es selbst zu unterstützen, indem Sie super.equals() aufrufen und dann die zusätzlichen Mitglieder vergleichen, die Sie hinzugefügt haben.

0voto

duffymo Punkte 298898

Ich überschreibe equals und hashCode für alle Objekte, die in java.util Collections API verwendet werden. Diese Klassen hängen normalerweise von den richtigen Überschreibungen ab.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X