Ich stieß gerade auf ein Problem, das durch Javas java.awt.geom.Area#equals(Area)
Methode verursacht wurde. Das Problem kann auf die folgende Einheit Test vereinfacht werden:Warum ist Java's Area # gleich Methode nicht überschreiben Objekt # ist gleich?
@org.junit.Test
public void testEquals() {
java.awt.geom.Area a = new java.awt.geom.Area();
java.awt.geom.Area b = new java.awt.geom.Area();
assertTrue(a.equals(b)); // -> true
java.lang.Object o = b;
assertTrue(a.equals(o)); // -> false
}
Nachdem einige am Kopf kratzen und Debugging, ich schließlich in der JDK Quelle sah, dass die Unterzeichnung des equals
Methode in Area
wie folgt aussieht:
public boolean equals(Area other)
Beachten sie, dass es funktioniert nicht@Override
die normale equals
Methode von Object
, sondern Überlastungen nur die Methode mit einer konkreteren Art. Daher rufen die beiden Aufrufe im obigen Beispiel verschiedene Implementierungen von equals
auf.
Da dieses Verhalten seit Java 1.2 vorliegt, nehme ich an, dass es sich nicht um einen Fehler handelt. Ich bin daher mehr daran interessiert herauszufinden, warum die Entscheidung wurde nicht richtig übersteuern die equals
Methode, aber gleichzeitig eine überlastete Variante. (Ein weiterer Hinweis, dass dies eine tatsächliche Entscheidung ist das Fehlen einer überschrieben hashCode()
Methode.)
Meine einzige Vermutung wäre, dass die Autoren befürchten, dass die langsame equals
Umsetzung für Bereiche ist nicht geeignet für den Vergleich Gleichheit bei der Platzierung Area
s in Set
, Map
, etc. Datenstrukturen. (Im obigen Beispiel könnten Sie zu einer HashSet
hinzufügen, und obwohl b
gleich a
ist, wird das Aufrufen von contains(b)
fehlschlagen.) Warum haben sie dann nicht einfach die fragwürdige Methode auf eine Weise benannt, die nicht mit einer solchen kollidiert grundlegendes Konzept wie die equals
Methode?
Beachten Sie, dass 'hashCode' ebenfalls nicht überschrieben wird.Ich denke, was sie hier tun, ist nur eine "Vergleich" -Methode, die zufälligerweise den gleichen Namen wie "Object.equals()" hat. Persönlich hätte ich ihm einen anderen Namen gegeben, um Verwirrung zu vermeiden. – RealSkeptic
Die Java-API folgt nicht immer den Best Practices, und das sieht nach einem Versehen aus. Versuchen Sie, diese Frage in den Oracle-Entwickler-E-Mail-Listen zu stellen und sehen Sie, was das offizielle Wort ist. Wenn es ein Versehen ist, war Sun/Oracle immer sehr zurückhaltend, API-Änderungen nach der Veröffentlichung vorzunehmen. Was könnte bedeuten, dass es als ein Versehen begann, das es in eine Freigabe machte, und jetzt gerade in der Zeit eingefroren ist. –
Siehe [Bug 4391558] (https://bugs.openjdk.java.net/browse/JDK-4391558) – RealSkeptic