Overriding toString method for complex object

This is (maybe) a pretty basic question, but I’d like to know if there are some consolidated best practices for overriding toString method for complex object.

Let’s say I have a class defined like this:

public class MyClass {
    private int id;
    private ClassWithLotsOfFields field1;
    private AnotherClassWithLotsOfFields field2;
    private List<ComplexObject> listOfComplexObjects;
    // accessors ...

and suppose ClassWithLotsOfFields, AnotherClassWithLotsOfFields and ComplexObject are declaring fields of “complex” types.

In these cases should I call toString for all these nested classes, creating a “gigantic” toString output or should I simplify the output string in any way?


For example: is it “acceptable” to print only certain fields of the “nested” objects? Or completely exclude them from the string output?


From the documentation of Object::toString:

Returns a string representation of the object. In general, the toString method returns a string that “textually represents” this object. The result should be a concise but informative representation that is easy for a person to read.

Emphasis mine.

That is very subjective indeed. There is no general rule of how to weigh these things. Many toString() implementations return the class name and then the toString() result of all fields. A particular implementation may look like this:

class SomeClass {
    private Alpha alpha;
    private Bravo bravo;

    public String toString() {
        return String.format("SomeClass(alpha=%s, bravo=%s)", alpha, bravo);

There even exist tools to autogenerate the toString() implementation, like Lombok.

However, the abovementioned example is mainly used for simpler classes. I have never seen complex objects like you are describing. If I had such a complex object, I would personally include everying, except for fields representing internal state.

But what’s more, I would also refrain from complex objects like you are describing, unless I absolutely have to.