我想要一种方法来覆盖具有循环引用的类的equals方法。以下是我的课程 EDIT :删除了用于获取方法和设置方法的代码
class Person implements Serializable{
private String fullName;
private Person friend;
// Getters and setters
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (friend == null) {
if (other.friend != null)
return false;
} else if (!friend.equals(other.friend))
return false;
if (fullName == null) {
if (other.fullName != null)
return false;
} else if (!fullName.equals(other.fullName))
return false;
return true;
}
}
在客户端类中,我有以下内容:
Person p1 = new Person();
Person p2 = new Person();
Person p3 = new Person();
p1.setFullName("nkuruza");
p2.setFullName("Another");
p3.setFullName("nkuruza");
p3.setFriend(p2);
p1.setFriend(p2);
p2.setFriend(p1);
在这种情况下,问题是调用equals方法,例如p1.equals(p3)产生StackOverflowException。
如何在不遇到此问题的情况下实现我的equals方法?
我先谢谢你。
答案 0 :(得分:2)
真正的答案是根据现实对您的课程进行建模。
实际上,定义一个人的真实方面是什么? 那就是身份,例如名字。
朋友的设置明天可能会改变,但您仍然是您!因此,换句话说:从该比较中排除好友字段。甚至更好:考虑不要将此关系记录为该类中的字段(如果有的话,它应该是列表,而不是单个实例)。但是,正如所说的那样,理想情况下,该信息应该在人员类的外部中!
答案 1 :(得分:1)
由于p1
的{{1}}设置为friend
,并且p2
的{{1}}设置为p2
,因此您的{{1} }方法最终导致两个friend
实例之间的无限调用循环:
p1
调用equals()
调用Person
(永远-或直到达到JVM当前配置的堆栈大小限制为止,此时它将抛出p1.equals(p2)
)< / p>
目前的解决方案可能是直接测试朋友的独特属性({{1}是迄今为止唯一的其他属性):
p2.equals(p1)
(...确保更新代码,以防止出现任何可能的空值)