Контракт equals
в отношении null
выглядит следующим образом:
Для любого ненулевого опорного значения
x
,x.equals(null)
долженreturn false
.
Это довольно странно, потому что если o1 != null
и o2 == null
, то мы имеем:
o1.equals(o2) // returns false
o2.equals(o1) // throws NullPointerException
Тот факт, что o2.equals(o1) throws NullPointerException
- это хорошо, потому что он предупреждает нас об ошибке программиста. И тем не менее, эта ошибка не была бы решена, если по разным причинам мы просто переключили ее на o1.equals(o2)
, которая просто "молчала бы" вместо этого.
Итак, вопросы:
- Почему это хорошая идея, что
o1.equals(o2)
долженreturn false
вместо метанияNullPointerException
? - Было бы плохой идеей, если, по возможности, мы переписываем контракт так, чтобы
anyObject.equals(null)
всегда бросалNullPointerException
вместо этого?
По сравнению с Comparable
В отличие от этого, Comparable
контракт говорит:
Обратите внимание, что
null
не является экземпляром какого-либо класса, аe.compareTo(null)
должен бросатьNullPointerException
, хотяe.equals(null)
возвращаетfalse
.
Если NullPointerException
подходит для compareTo
, почему это не для equals
?
Связанные вопросы
Чистый семантический аргумент
Это фактические слова в Object.equals(Object obj)
:
Указывает, является ли какой-либо другой объект "равным" этому.
А что такое объект?
Объекты JLS 4.3.1
Объект - это экземпляр класса или массив.
Контрольные значения (часто просто ссылки) являются указателями на эти объекты и специальной ссылкой
null
, которая ссылается на отсутствие объекта.
Мой аргумент из этого угла действительно прост.
-
equals
проверяет, равен ли какой-либо другой объект "<" t228 > -
null
ссылка не дает другого объекта для теста - Поэтому
equals(null)
должен бросатьNullPointerException