如何为两个指向彼此的对象编写toString

时间:2014-04-23 20:15:35

标签: java

class A {
    String one;
    String two;
    B bRef;
    Collection<B> bCollRef;

    A(String one, String two)
    {
        this.one = one;
        this.two = two;
    }

    //setters for bRef and bCollRef;
}

class B {
    String three;
    A a;

    B(String three)
    {
        this.three = three;
    }

    //setter for a
}

A a1 = new A(...);
A a2 = new A(...);
a1.setbRef(new B(str,a2));
a2.setbCollRef(new B(str,a1));

a2与a1的子项相似,a1是a2的父项。什么是为这些类编写toString方法并避免stackoverflow错误的最佳方法。

4 个答案:

答案 0 :(得分:0)

a2可能是&#34;就像a1&#34;的孩子一样,但它也像a1的父母一样。您的数据结构中有一个循环。你可以做很多事情,这取决于你想要的样子;我想到的第一个是toString来测试其他对象的本地引用,看它是否包含对自身的引用,并相应地处理事情。

答案 1 :(得分:0)

这可行,假设您在A

中有B引用的公共访问者
class A {
    String one;
    String two;
    B bRef;
    Collection<B> bCollRef;

    A(String one, String two)
    {
        this.one = one;
        this.two = two;
    }

    //setters for bRef and bCollRef;

    @Override
    public void toString(){

        if(bRef.geta() == this)
            //you have a circular reference, dont step into it(don't call the next toString() method) and you won't stackoverflow here
        else
            //no circular reference, no problems here, tostring it as you will

    }
}

现在,您如何编写toString()方法取决于您希望如何将对象转换为字符串...这个简单的if语句将保护您免受循环引用的影响。如果您有更多可能使事情复杂化的参考文献,我建议您退后一步,重新考虑您的工作方式,您的对象不需要查看每个其他对象。

如果你有一个更高阶的循环参考情况,并且引用b1b2就像a1 -> b1 -> a2 -> b2 -> a1那么你需要编写这样的代码..在实践中你会想要但是要非常小心空引用:

    @Override
    public String toString(){
        //do tostring stuff on current object
        A nextA = bRef.geta(); 
        //do tostring stuff on next stuff

        while(nextA != this){
             nextA = nextA.getbRef.getA();
             //unravel the references until you come around full-circle
        }

    }

答案 2 :(得分:0)

可以通过多种方式完成,具体取决于您的需求。

一种解决方案可能是使toString()方法接受参数,如下所示:

//in class A
@Override
String toString(){
    return toString(true);
}

/**
@Param subclass Should subclass info be included 
*/
String toString(boolean subclass){
    String text = /* details from current class */;
    if (subclass && bRef != null)
        text += bRef.toString(false);
    return text;
}

同样可以应用于课程B,只需将bRef替换为a

当你需要来自某个对象的String时,只需调用toString()(不带参数)


但是,如果您的案例中有这样的引用,例如:a1 -> b1; b1 -> a2; a2 -> b2; b2 -> a1

然后这种方法会更好:

//in class A
@Override
String toString(){
    return toString(new Stack<Object>());
}

/**
@Param stack Holds all objects that have been called
*/
String toString(Stack stack){
    String text = /* details from current class */;
    if (bRef != null && stack != null && stack.search(bRef) == -1)
    {
        stack.push(bRef);
        text += bRef.toString(stack);
    }
    return text;
}

答案 3 :(得分:-1)

我不知道toStringAB的看法是什么,但我只是猜猜。

class A {
    private String getStringRepresentation() {
        return one + " | " + two;
    }
    public String toString() {
        return bRef.toString();
    }
}

class B {
    public String toString() {
        return three + "[" + aRef.getStringRepresentation() + "]"
    }
}