为什么Java的`equals()`默认情况下不进行深度比较

flo*_*w2k 7 java equals

众所周知,equals()对象的方法如果不被覆盖,则是"浅比较",等同于使用"=="运算符.(例如,参见https://docs.oracle.com/javase/tutorial/java/IandI/objectclass.html.)

问题:为什么Java equals()默认不提供"深度比较" 方法?也就是说,将equals()递归地调用每个实例变量.最终,递归将达到原始类型并停止.如果这种深度比较等于默认值,是否有任何缺点?

And*_*mas 11

如果这种深度比较等于默认值,是否有任何缺点?

是.这些包括:

  • 默认实现无法区分作为对象逻辑值一部分的引用,以及仅与其他对象关联的引用.例如,假设您有一个引用公司的Person类.您有两个具有相同名称的Person实例,SSN,DOB等.一个引用旧公司.您可能希望引用相同实际人员的两个Person实例相等,即使其中一个具有过时关联.
  • 深度相等测试通常比当前默认测试慢,可能明显更慢.通常这是不必要的.当前的默认值确保相等测试总是很快,除非有人明确指定.
  • 深度比较需要处理引用中的循环.这需要一些方法来记住已遍历的对象.这将需要内存来跟踪这些对象,可能需要大量内存.相等测试可能导致OutOfMemoryError.

当前的默认实现很快,不做任何假设.这是一个很好的默认值.有时,您将需要使用您对对象的逻辑值包含的内容的了解来覆盖默认值,而不管其根物理表示形式如何.