Договор 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)
:
Указывает, равен ли какой-либо другой объект этому.
А что такое объект?
объект представляет собой экземпляр класса или массив.
Контрольные значения (часто просто ссылки ) являются указателями на эти объекты, и специальная null
ссылка, которая ссылается на отсутствие объекта .
Мой аргумент с этой точки зрения действительнопросто.
equals
проверяет, является ли какой-либо другой объект"равным" this
null
ссылка не дает другой объект для теста - Следовательно,
equals(null)
должен выбросить NullPointerException