使用循环引用Java

时间:2019-03-10 23:01:23

标签: java

我想要一种方法来覆盖具有循环引用的类的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方法?

我先谢谢你。

2 个答案:

答案 0 :(得分:2)

真正的答案是根据现实对您的课程进行建模。

实际上,定义一个人的真实方面是什么? 那就是身份,例如名字。

朋友的设置明天可能会改变,但您仍然是您!

因此,换句话说:从该比较中排除好友字段。甚至更好:考虑不要将此关系记录为该类中的字段(如果有的话,它应该是列表,而不是单个实例)。但是,正如所说的那样,理想情况下,该信息应该在人员类的外部中!

答案 1 :(得分:1)

由于p1的{​​{1}}设置为friend,并且p2的{​​{1}}设置为p2,因此您的{{1} }方法最终导致两个friend实例之间的无限调用循环:

p1调用equals()调用Person(永远-或直到达到JVM当前配置的堆栈大小限制为止,此时它将抛出p1.equals(p2))< / p>

目前的解决方案可能是直接测试朋友的独特属性({{1}是迄今为止唯一的其他属性):

p2.equals(p1)

(...确保更新代码,以防止出现任何可能的空值)