添加equals()
和hashCode()
方法是否有可能破坏已经存在的代码?
我有一个包含3个字段,getter和setter的类:
public class Person {
private final String name;
private final List<Friend> friends;
private final Integer age;
为了测试此类,我使用了:isEqualToComparingFieldByField()
方法比较两个Person
对象,而不是添加equals()
和hashCode()
。其他解决方案是重写equals()
和hashCode()
并使用assertEquals()
比较这些对象,但是我可以完全确定它不会破坏任何对象吗?
我可以完全确定它不会破坏任何东西吗?
没有您正在将相等的含义从引用标识更改为一种值相等。您将打破依赖于当前行为的所有内容。例如,这是一些有效的代码:
Person person1 = new Person("Foo", 100);
Person person2 = new Person("Foo", 100);
// This is fine. Two distinct Person objects will never be equal...
if (person1.equals(person2)) {
launchNuclearMissiles();
}
您建议的更改将打破这一点。
您实际上是否具有类似的代码?很难说。
[更有可能,如果您想更改hashCode
以包括来自List<Friend>
的哈希,除非类型实际上是不可变的,否则您很容易破坏代码。例如:
Map<Person, String> map = new HashMap<>();
Person person = new Person("Foo", 100);
map.put(person, "Some value");
// If this changes the result of hashCode()...
person.addFriend(new Friend("Bar"));
// ... then you may not be able to find even the same object in the map.
System.out.println(map.get(person));
根本上,您需要知道其他代码使用Person
,因此您知道它所依赖的内容。如果Person
是不可变的,这将使生活变得更简单,因为您无需担心第二种问题。 (为可变类型覆盖equals()
和hashCode()
是一项根本危险的工作。)
Person
,例如在地图,集合等中,则覆盖equals()
和hashCode()
显然可以更改某些操作的结果。