当我读一本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));
问题内容: 为什么以下代码不起作用(Python 2.5.2)? 我想创建一个类似的类,但具有不同的功能。显然我的函数永远不会被调用。而是调用原始文件并失败,因为它需要3个参数,而我传入了一个。 这里发生了什么?这是一个线索吗? 谢谢! 问题答案: 关于其他几个答案,这与用C本身实现的日期无关。该方法不做任何事情,因为它们是 不可变的 对象,因此构造函数()应该完成所有工作。您会看到相同的行为将i
问题内容: 为什么不应该使用函数的技术原因是什么?(例如,或)? 为什么我要使用其他东西,即使它们在我的网站上工作? 如果它们在我的网站上不起作用,为什么我会收到类似的错误 警告:mysql_connect():没有那个文件或目录 问题答案: MySQL 扩展: 未在积极开发中 被正式弃用的PHP 5.5(发布2013年6月)。 自 PHP 7.0起 已完全删除 (2015 年 12 月发布) 这
问题内容: 想要改善这篇文章吗? 提供此问题的详细答案,包括引文和为什么答案正确的解释。答案不够详细的答案可能会被编辑或删除。 为什么不应该使用功能的技术原因是什么?(例如,或)? 即使我的网站上可以工作,我为什么还要使用其他东西? 如果它们在我的网站上不起作用,为什么会出现类似 警告:mysql_connect():没有这样的文件或目录 问题答案: MySQL扩展: 没有积极发展 被 正式 弃用
问题内容: 在本文中, Nick Coghlan讨论了PEP 435类型的 一些设计决策,以及如何将其子类化以提供不同的体验。 但是,我给出的建议(我是stdlib的主要作者)关于使用元类的建议是,在没有充分好的理由的情况下不应该这样做- 例如,无法使用类装饰器或专用工具来完成所需的工作隐藏任何丑陋的功能;而在我自己的工作,我已经能够做到我需要什么简单的使用,在创建时,和/或正常类/实例方法类:
问题内容: 之间有什么区别: 和 我知道JPanel是GUI组件的容器,但我确实看不到使用它的实用程序。当然,我错了,但我是从Swing开始的,所以…为什么我应该使用JPanel?真正的目的是什么? 问题答案: 为什么我应该使用JPanel? 您可以使用JPanel获得以下一项或多项好处: 将组件分组在一起。 为了更好地组织您的组件。 为了使我们能够使用 多种布局 并组合其效果。(例如,用于数字键
我的老师让我这样做,但在评论区我被告知我不应该这样做。 为什么?