Most efficient way to prevent an infinite recursion in toString()?

前端 未结 9 1469
南方客
南方客 2020-12-15 21:20

To string on a collection can get into a infinite loop if somewhere in the graph of collected items is a reference back to itself. See example below.

Yes, good cod

相关标签:
9条回答
  • 2020-12-15 21:51

    I recommend using ToStringBuilder from Apache Commons Lang. Internally it uses a ThreadLocal Map to "detect cyclical object references and avoid infinite loops."

    0 讨论(0)
  • 2020-12-15 21:53

    When I have to iterate over risky graphs, I usually make a function with a decrementing counter.

    For example :

    public String toString(int dec) {
        if (  dec<=0 ) {
            return "{skipping recursion}";
        } else {
            return super.toString(dec-1);
        }
    }
    
    public String toString() {
        return toString(100);
    }
    

    I won't insist on it, as you already know it, but that doesn't respect the contract of toString() which has to be short and predictable.

    0 讨论(0)
  • 2020-12-15 21:58

    The simplest way: don't call toString() on the elements of a collection or a map, ever. Just print a [] to indicate that it's a collection or map, and avoid iterating over it entirely. It's the only bullet-proof way to avoid falling in an infinite recursion.

    In the general case, you can't anticipate what elements are going to be in a Collection or Map inside another object, and the dependency graph could be quite complex, leading to unexpected situations where a cycle occurs in the object graph.

    What IDE are you using? because in Eclipse there's an option to explicitly handle this case when generating the toString() method via the code generators - that's what I use, when an attribute happens to be a non-null collection or map print [] regardless of how many elements it contains.

    0 讨论(0)
提交回复
热议问题