Это плохая идея, если функция equals (null) вместо этого выдает исключение NullPointerException? - PullRequest
75 голосов
/ 22 мая 2010

Договор 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):

Указывает, равен ли какой-либо другой объект этому.

А что такое объект?

JLS4.3.1 Объекты

объект представляет собой экземпляр класса или массив.

Контрольные значения (часто просто ссылки ) являются указателями на эти объекты, и специальная null ссылка, которая ссылается на отсутствие объекта .

Мой аргумент с этой точки зрения действительнопросто.

  • equals проверяет, является ли какой-либо другой объект"равным" this
  • null ссылка не дает другой объект для теста
  • Следовательно, equals(null) должен выбросить NullPointerException

Ответы [ 11 ]

0 голосов
/ 22 мая 2010

Это сложный вопрос.Для обратной совместимости вы не можете этого сделать.

Представьте себе следующий сценарий

void m (Object o) {
 if (one.equals (o)) {}
 else if (two.equals (o)) {}
 else {}
}

Теперь при равенстве с возвращением false будет выполнено предложение else, но не при вызове исключения.

Кроме того, null на самом деле не равно "2", поэтому имеет смысл возвращать false.Тогда, вероятно, лучше настаивать на том, чтобы null.equals ("b") возвращал также false:))

Но это требование создает странное и несимметричное равенство.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...