当我读一本Java书籍时,作者曾说过,在设计类时,equals()
与继承一起使用通常是不安全的。例如:
public final class Date {
public boolean equals(Object o) {
// some code here
}
}
在上面的类中,我们应放置final
,以便其他类不能从此继承。我的问题是,为什么允许另一个类从中继承是不安全的?
因为很难(不可能?)做到正确,尤其是对称属性。
说你有一Vehicle
堂课Car extends Vehicle
。Vehicle.equals()
产生true
如果参数也是Vehicle
并且具有相同的重量。如果要实现,Car.equals()
则true
仅当参数也是汽车(重量除外)时,它才应屈服,并且还应比较制造商,发动机等。
现在想象下面的代码:
Vehicle tank = new Vehicle();
Vehicle bus = new Car();
tank.equals(bus); //can be true
bus.equals(tank); //false
true
如果巧合的是,油箱和客车的重量相同,则第一个比较可能会得出结果。但是由于坦克不是汽车,因此将其与汽车相比较总是可以得到收益的false
。
您有几种解决方法:
严格:两个对象只有且具有完全相同的类型(并且所有属性都相同)时才相等。这很不好,例如,当您几乎没有子类化以添加某些行为或装饰原始类时。一些框架也在不引起您注意的情况下对您的类进行子类化(Hibernate,带有CGLIB代理的Spring AOP ...)
松散的:如果两个对象的类型“兼容”并且它们的内容(语义上)相同,则它们是相等的。例如,如果两个集合包含相同的元素,则它们是相等的,一个HashSet
与另一个无关紧要TreeSet
(感谢@veer指出这一点)。
这可能会产生误导。取2 LinkedHashSet
s(其中插入顺序作为合同的一部分很重要)。但是,由于equals()
仅考虑原始Set
合同,因此true
即使对于明显不同的对象,该比较也会产生收益:
Set<Integer> s1 = new LinkedHashSet<Integer>(Arrays.asList(1, 2, 3));
Set<Integer> s2 = new LinkedHashSet<Integer>(Arrays.asList(3, 2, 1));
System.out.println(s1.equals(s2));
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句