我一直都知道Java中有两种类型的相等,
.equals()
方法测试两个对象是否在非空对象引用上实现等价关系。==
运算符测试两个基本类型或内存位置是否相等。以下几页更详细地介绍了这些语言基础知识。
如果比较两个null
对象引用的值相等,那么这些链接中没有明确指定的内容是什么。隐含的假设是应该抛出NullPointerException
,但这不是ObjectUtils.equals()方法所做的,这可能被认为是最佳实践实用方法。
令我担心的是Apache Commons似乎已经有效地在后门引入了第三种平等的Java,并且已经混乱的状态可能会变得更加复杂。我称之为平等的第三个衡量标准,因为它试图测试值的相等性,当它失败时,它又回到测试参考相等性。 Apache Commons相等测试与值相等和引用相等有许多相似之处,但也有明显的不同。
我是否有理由担心并希望尽可能避免使用ObjectUtils.equals()
?
有没有论据声称ObjectUtils.equals()
提供了另外两种平等衡量标准的有用结合?
似乎没有就这个问题达成共识意见,但我决定将Bozho标记为正确,因为他最好把我的注意力放在我现在认为是无效安全等于检查的最大问题上。我们都应该编写 fail-fast 代码,解决为什么要比较两个空对象的价值平等的根本原因,而不是试图在地毯下扫描问题。
答案 0 :(得分:10)
以下是ObjectUtils.equals(..)
的代码:
public static boolean equals(Object object1, Object object2) {
if (object1 == object2) {
return true;
}
if ((object1 == null) || (object2 == null)) {
return false;
}
return object1.equals(object2);
}
ObjecUtils docs明确指出传递的对象可以为空。
现在,如果比较两个true
,是否应该返回null
。在我看来 - 不,因为:
NullPointerException
null
传递给比较意味着它们来自某个地方而不是“真实”物体,可能是由于某些问题。在这种情况下,单独比较它们是错误的 - 程序流程应该在此之前停止。equalOrBothNull()
的方法 - 它与null实现中的equals
方法不同。答案 1 :(得分:5)
我是关心和想要的 避免使用 ObjectUtils.equals()在哪里 可能的?
没有。您需要考虑的等于您的要求。并且想要考虑两个空值相等且任何非null不等于null而不必处理NullPointerExceptions是一个非常非常常见的要求(例如,当您想要从setter触发值更改事件时)。
实际上,equals()
一般应该工作的方式,通常,实现了一半的behvaiour(Object.equals()
状态的API文档“对于任何非null引用值x
,x.equals(null)
应该返回false。“) - 它不起作用主要是由于技术限制(语言设计没有multiple dispatch更简单)。
答案 2 :(得分:1)
如果你担心这个,那么你可以1)不使用这个方法2)写你自己的包装
public class MyObjectUtils {
public static boolean equals(Object obj1, Object obj2) {
return obj1 != null && obj2 != null && ObjectUtils.equals(obj1, obj2);
}
}
对我来说,允许null等于null似乎很奇怪,但这似乎不是一个大问题。在大多数情况下,如果一个或多个对象为空,我不希望我的应用程序甚至进入涉及相等性测试的代码路径。