equals
方法在处理null
时的契约如下:
对于任何非
null
引用值x
,x.equals(null)
应该返回false
。
这是相当奇怪的,因为如果 o1 != null
且 o2 == null
,那么我们有:
o1.equals(o2) // returns false
o2.equals(o1) // throws NullPointerException
"
o2.equals(o1)
抛出NullPointerException
是一件好事,因为它提醒我们程序员的错误。然而,如果由于各种原因我们只是将其切换到o1.equals(o2)
,那么这个错误就不会被捕获,而只会“静默失败”。
所以问题是:
- 为什么
o1.equals(o2)
应该返回false
而不是抛出NullPointerException
? - 如果可能的话,我们是否应该重写合同,使得
anyObject.equals(null)
总是抛出NullPointerException
?
与Comparable
的比较
相比之下,这是Comparable
合同所说:
请注意,
null
不是任何类的实例,e.compareTo(null)
应抛出NullPointerException
,即使e.equals(null)
返回false
。
如果对于compareTo
来说,NullPointerException
是合适的,那么为什么对于equals
不是呢?
相关问题
一个纯语义的论点
这是Object.equals(Object obj)
文档中的实际词语:
指示是否有一些其他对象与此对象“相等”。
那么什么是对象?
JLS 4.3.1 对象
对象是一个类实例或数组。
引用值(通常只是引用)是指向这些对象的指针,有一个特殊的
null
引用,它没有任何对象。
从这个角度来说,我的论点非常简单。
equals
测试是否有一些其他对象与this
“相等”null
引用没有为测试提供其他对象- 因此,
equals(null)
应该抛出NullPointerException