(конечно, если вы не переопределите Object.equals() ).
Я наткнулся на довольно любопытный вопрос переполнения стека от пользователя Frank:
Почему Java-метод Area # equals не переопределяет Object # equals?
Интересно, что существует Area.equals(Area) который действительно принимает аргумент Area вместо аргумента Object как объявлено в Object.equals() . Это приводит к довольно неприятному поведению, как обнаружил Фрэнк:
|
1
2
3
4
5
6
7
8
9
|
@org.junit.Testpublic 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} |
Технически, правильно, что AWT Area был реализован таким образом (поскольку hashCode() тоже не реализован), но способ, которым Java разрешает методы, и способ, которым программисты переваривают код, который был написан, как приведенный выше код, это действительно ужасная идея перегружать метод equals.
Нет статических равных, либо
Эти правила также справедливы для статических методов equals() , таких как, например, Apache Commons Lang ‘s
|
1
|
ObjectUtils.equals(Object o1, Object o2) |
Путаница возникает из-за того, что вы не можете статически импортировать этот метод equals:
|
1
|
import static org.apache.commons.lang.ObjectUtils.equals; |
Когда вы сейчас набираете следующее:
|
1
|
equals(obj1, obj2); |
Вы получите ошибку компилятора:
Метод equals (Object) в типе Object не применим для аргументов (…,…)
Причина этого заключается в том, что методы, которые находятся в области действия текущего класса и его супертипов, всегда будут скрывать все, что вы импортируете таким образом. Следующее также не работает:
|
01
02
03
04
05
06
07
08
09
10
11
|
import static org.apache.commons.lang.ObjectUtils.defaultIfNull;public class Test { void test() { defaultIfNull(null, null); // ^^ compilation error here } void defaultIfNull() { }} |
Подробности в этом вопросе переполнения стека .
Вывод
Вывод прост. никогда не перегружайте ни один из методов, объявленных в Object (переопределение, конечно, хорошо). Это включает:
-
clone() -
equals() -
finalize() -
getClass() -
hashCode() -
notify() -
notifyAll() -
toString() -
wait()
Конечно, было бы замечательно, если бы эти методы не были объявлены в Object в первую очередь, но этот корабль отплыл 20 лет назад.
| Ссылка: | Не называй свой метод «Равным» от нашего партнера по JCG Лукаса Эдера из блога JAVA, SQL и JOOQ . |