Я столкнулся с проблемой, вызванной Java java.awt.geom.Area#equals(Area)
. Проблема может быть упрощена до следующих unit test:
@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
}
После некоторой царапины и отладки головы я наконец увидел в источнике JDK, что подпись метода equals
в Area
выглядит следующим образом:
public boolean equals(Area other)
Обратите внимание, что это не @Override
обычный equals
метод из Object
, а вместо этого просто перегружает метод более конкретным типом. Таким образом, два вызова в приведенном выше примере заканчиваются вызовом различных реализаций equals
.
Поскольку это поведение присутствует с Java 1.2, я предполагаю, что это не считается ошибкой. Поэтому я больше заинтересован в том, чтобы выяснить, почему было принято решение не правильно переопределять метод equals
, но в то же время обеспечить перегруженный вариант. (Еще один намек на то, что это было фактически принято, - отсутствие перезаписанного метода hashCode()
.)
Мое единственное предположение заключалось в том, что авторы опасались, что медленная реализация equals
для областей непригодна для сравнения равенства при размещении Area
в Set
, Map
и т.д. datastructures. (В приведенном выше примере вы могли бы добавить a
в HashSet
, и хотя b
равен a
, вызов contains(b)
завершится с ошибкой.) И опять же, почему они не просто назвали сомнительный метод таким образом, чтобы он не сталкивался с таким фундаментальным понятием, как метод equals
?