这等于合法吗?
我遇到了这段代码。我从来没有见过Equals以这样的方式实现。让我印象深刻的是,它真的很"整洁",从这个意义上说,它只需要一行样板。
然而,我以前从未见过这种方法,这让我产生了怀疑。根据Java Equals和hashCode的合同,以下实现合法吗?
@Override
public boolean equals(Object o)
{
return this == o || o instanceof DetailsPageTrackingRequest
&& this.hashCode() == o.hashCode();
}
@Override
public int hashCode()
{
//java.util.Objects
return Objects.hash(pageTrackingRequest, searchId, productId);
}
解决方案
由于其他答案中已经说明的原因,这可能不是一个好主意。
至于"法律"方面,Contract of Object.equals说明
Equals方法在非空对象引用上实现等价关系:
- 它是自反式的:对于任何非空的引用值x,x.equals(X)应返回True。
- 它是对称的:对于任何非空的引用值x和y,当且仅当y.equals(X)返回True时,x.equals(Y)才应返回True。
- 它是可传递的:对于任何非空的引用值x、y和z,如果x.equals(Y)返回True,y.equals(Z)返回True,则x.equals(Z)应返回True。
- 它是一致的:对于任何非空的引用值x和y,多次调用x.equals(Y)将一致返回True或一致返回False,前提是对象上的等于比较中使用的信息未被修改。
- 对于任何非空引用值x,x.equals(空)应返回FALSE。
逐步:
- 自反式:是的,由于
this == o
- 对称:由于使用了
instanceof
,我们需要查看所有超类和子类以确保 - 传递性:取决于对称要求,否则为是
- 一致:是
x.equals(null)
应返回FALSE:是,由于instanceof
因此,从纯粹的法律角度来看,这取决于继承层次结构中的其他实现是否违反了对称性和传递性--请参阅Any reason to prefer getClass() over instanceof when generating .equals()?的答案。
除此之外,考虑到hashCode
不需要为非等价实例生成不同的值,这通常不是定义相等的好方法。
示例:
具有两个字段的不可变点类x
和y
class Point {
final int x;
final int y
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
->有2^32 * 2^32 = 2^64
个不同的状态,但只有2^32
个可能的哈希码。这意味着,根据equals
的实现,有许多点被视为相等。
另请参阅此示例equals and hashCode: Is Objects.hash method broken?,了解有关使用Objects.hash
和Strings
创建的散列的散列冲突的问题。
相关文章