Java 零与等号的对称性

Java 零与等号的对称性,java,null,nullpointerexception,equals,symmetric,Java,Null,Nullpointerexception,Equals,Symmetric,平等应该是对称的,对吗 Object someObject = new Object(); Object NULL = null; NULL.equals(someObject) => NullPointerException someObject.equals(NULL) => false 不让第二种形式抛出一个NullPointerException?在第一种情况下,equals()方法不抛出NPE,因此不能使用该参数。对称性是equals()方法契约的一部分。因为在第二种情

平等应该是对称的,对吗

Object someObject = new Object();
Object NULL = null;

NULL.equals(someObject) => NullPointerException
someObject.equals(NULL) => false

不让第二种形式抛出一个
NullPointerException

在第一种情况下,equals()方法不抛出NPE,因此不能使用该参数。对称性是equals()方法契约的一部分。

因为在第二种情况下,您没有访问
null
对象的方法。不平衡的不是平等的概念,而是你如何访问它。

平等在理论上当然被定义为对称的,但它在不存在的对象上也根本没有定义(这就是null所代表的)

因此,应用于null的任何行为都同样有效。它可以返回一只活兔子,但仍然不违背平等的理论定义


在这种情况下,代表Java设计人员的一个相当合理的实现决策是,对空值调用equals应该抛出一个NullPointerException,因为这与对空值调用任何其他方法是一致的。

第二个示例不是对称的示例,因为它违反了关于对象和

对于任何非空参考值x,x.equals(null)应返回 错

我会选择

someObject.equals(null);
不让第二个表单抛出 NullPointerException

在这种情况下,它不会抛出NullPointerException


在这里,我们可以确定
equals()
要调用的对象是
非NULL
第二位不会抛出NPE,因为您没有取消引用NULL指针。该代码返回false,因为您正在将值与非值进行比较

equals(null)
将始终返回false,因为不存在null值。对象和原语都不能有值
null
,因为Java中不存在该概念
null
是表示null引用的文本,这就是我们比较引用的原因,例如
if(obj==null)
。请参阅Java语言规范。换句话说,您正在将
someObject
的值与空引用进行比较


您可以创建自己的对象,覆盖
equals
,并返回true,但这将违背对象中的定义。

您可能会认为异常会有所不同,或者根本无法编译。@0A0D-我认为这只是保持一致性的实际问题-您希望在运行时取消对null指针的引用以抛出null指针异常,否则人们会得到对可能的原因感到困惑……我可以看出。这看起来很有趣,因为它明确指出它只涉及非空引用。由于null在这里显式为null,人们会认为编译器会立即停止。这个值在运行时之前就已经知道了。好吧,但是为什么契约的定义是这样的呢?我们从这种不对称中得到了什么?为什么不说“
x.equals(null)
应该抛出一个
NullPointerException
”?@FredOverflow:因为NullPointerException是一个运行时异常,当它遵循Object.equals()契约的规则时,为异常抛出一个异常是没有意义的。@Fred,
null
不是一个值,因此对象不能等于null,正如您可以将
null
赋值给原语一样。当您执行检查
if(x==null)
时,您实际上是在检查指针引用的地址。因此,合同被定义为在与null进行比较时不会引发异常,因为如果与null进行比较会引发异常,这会违反合同吗?这不是一个很有说服力的论点。我还可以说,如果合同被定义为在null上抛出异常,那么抛出该异常将完全符合合同。@FredOverflow:这对NullPointerException没有意义,因为您没有取消引用null指针。无法编译语句
null.equals(someObject)
,至少是我。你是如何编译它的?可能是@Paul的复制品:显然是伪代码。现在好多了?:)@弗雷德,不是真的。如果你花2秒钟的时间阅读API,你会看到“equals方法在非null对象引用上实现了一个等价关系”。你会问“为什么Java的行为不像我认为的那样,而不是它在API中是如何定义的?”如果你仔细阅读null的定义,可能会有所帮助。我在下面的回答中链接到Java语言规范。@Fred,我一点也不同意,让equals抛出异常对编程来说是可怕的。调用
equals()
时,我只关心true和false。在多年的编程生涯中,我从未关注过第三种状态:未定义(参见)。在调用
equals
之前,是否要将每个对equals的调用包装在try-catch块中,或检查null?我肯定他妈的没有。如果您需要一个3值的equals(这正是您所提倡的…真、假、异常),那么在调用equals或编写接口之前,只需检查null。对称性是合同的一部分,仅适用于非null值。@Paul:没错,但问题是为什么会这样,我指出这个问题的前提是有缺陷的,因为equals()没有抛出NPE。