如果equals(null)抛出NullPointerException,这是一个坏主意吗?

pol*_*nts 75 java null equals nullpointerexception

合同equals与问候null,如下所示:

对于任何非空引用值x,x.equals(null)应该return false.

这是相当奇特的,因为如果o1 != nullo2 == null,那么我们有:

o1.equals(o2) // returns false
o2.equals(o1) // throws NullPointerException
Run Code Online (Sandbox Code Playgroud)

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测试一些其他对象是否"等于"this
  • nullreference没有给出测试的其他对象
  • 因此,equals(null)应该抛出NullPointerException

Sea*_*wen 102

关于这种不对称是否不一致的问题,我想不是,我推荐你到这个古老的禅宗:

  • 问任何一个男人,如果他和下一个男人一样好,每个人都会说是.
  • 问任何一个人他是否和没有人一样好,每个人都会说不.
  • 问任何人是否和任何男人一样好,你永远不会得到答复.

那一刻,编译器达成了启蒙.

  • 我想知道Java编程语言的设计者是否真的想到了这一点,或者他们是否只是没注意到不对称...... ;-) (6认同)

duf*_*ymo 19

一个例外真的应该是一个例外的情况.空指针可能不是程序员错误.

你引用了现有的合同.如果您决定违反惯例,那么在所有这些时间之后,当每个Java开发人员都期望等于返回false时,您将会做出意想不到的事情并且不受欢迎会使您的课程成为一个贱民.

我不能不同意.我不会重写equals来一直抛出异常.如果我是它的客户,我会替换任何那样做的类.


小智 8

想想.equals与==和.compareTo如何与比较运算符>,<,> =,<=相关.

如果您打算使用.equals将对象与null进行比较应该抛出一个NPE,那么您必须说这个代码也应该抛出一个:

Object o1 = new Object();
Object o2 = null;
boolean b = (o1 == o2); // should throw NPE here!
Run Code Online (Sandbox Code Playgroud)

o1.equals(o2)和o2.equals(o1)之间的区别在于,在第一种情况下,您将某些内容与null进行比较,类似于o1 == o2,而在第二种情况下,equals方法从未实际执行过所以没有任何比较发生.

关于.compareTo契约,将非null对象与null对象进行比较就像尝试这样做:

int j = 0;
if(j > null) { 
   ... 
}
Run Code Online (Sandbox Code Playgroud)

显然这不会编译.您可以使用自动拆箱来进行编译,但是在进行比较时会得到一个NPE,这与.compareTo契约一致:

Integer i = null;
int j = 0;
if(j > i) { // NPE
   ... 
}
Run Code Online (Sandbox Code Playgroud)