Apache Commons ObjectUtils equals equals方法测试了什么样的平等?

我一直认为Java中有两种类型的平等,

  • 值相等 :使用该方法来测试两个对象在非空对象引用上实现等价关系。.equals()
  • 引用相等:使用运算符来测试两个基元类型或内存位置是否相等。==

以下页面更详细地介绍了这些语言基础知识。

这些链接中没有明确指定的是,如果比较两个对象引用的值相等性,应该发生什么情况。隐含的假设是应该抛出 a,但这不是 ObjectUtils.equals() 方法所执行的操作,该方法可能被认为是最佳实践实用工具方法nullNullPointerException

令我担心的是,Apache Commons似乎已经有效地在后门将第三种平等措施引入Java,并且已经令人困惑的状况可能变得更加复杂。我称之为第三种平等度量,因为它试图测试价值相等性,当它失败时,它会回退到测试参考相等性。Apache Commons相等性测试与值相等性和参考相等性有许多相似之处,但也明显不同。

我担心并希望尽可能避免使用吗?ObjectUtils.equals()

是否有论据可以声称这为其他两种平等措施提供了有用的结合?ObjectUtils.equals()

选择的答案

在这个问题上似乎没有达成共识的意见,但我决定将Bozho标记为正确,因为他最好地引起我的注意,我现在认为是零安全等于检查的最大问题。我们都应该编写快速失败的代码,以解决为什么比较两个空对象以实现值相等的根本原因,而不是试图将问题扫地出门。


答案 1

这是代码: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 文档明确指出,传递的对象可以为 null。

现在关于是否应该返回的问题,如果你比较两个s。在我看来 - 不,因为:truenull

  • 当你比较两个对象时,你可能会在以后用它们做一些事情。这将导致NullPointerException
  • 通过两个s进行比较意味着它们来自某个地方而不是“真实”对象,可能是由于某些问题。在这种情况下,单独比较它们是错误的 - 程序流应该在此之前停止。null
  • 在我们这里使用的自定义库中,我们有一个名为 - 的方法与此实用程序中 null 比较中的方法不同。equalOrBothNull()equals

答案 2

我是否有权担心并希望尽可能避免使用ObjectUtils.equals()?

不。您需要考虑的平等取决于您的要求。想要考虑两个 null 相等,并且任何非 null 不等于 null 而不必处理 NullPointerExceptions 是一个非常非常常见的要求(例如,当您想要从 setter 触发值更改事件时)。

实际上,这是一般应该如何工作,通常,一半的behvaiour是实现的(API文档的状态“对于任何非空引用值,应该返回false.”) - 相反,它不起作用主要是由于技术限制(该语言的设计没有多次调度以更简单)。equals()Object.equals()xx.equals(null)