An extensible implementation of the toString() method

The toString() method which is definied by Java’s object class is used by many libraries, frameworks and the JVM itself to output information about an object. Especially when an when error occurs. But the default implementation which output the name of the class and the hash code of the object often not helpful. Therefore it is recommend to overwrite the default implementation.

But this can become quite cumbersome if you have an hierarchy of objects. You don’t want the repeat yourself and write the same code in the child class which have already written in the parent class. In this article I want do show a possible way how an extensible implementation of the toString() might look.

We use the following beans as examples. Getters and setters as well as equals and hashCode implementations have been omitted.

public class Vehicle {
    private String name;
    private String brand;
    private int maxSpeed;
}

public class Car extends Vehicle{
    private int seats;
}

public class Truck extends Vehicle {
    private int maxLoad;
}

On the base class we overwrite the toString() method as follows:

public final String toString() {
    return toString("");
}

public String toString(final String data) {
    return String.format("%s { name = \"%s\", brand = \"%s\", " +
                         "maxSpeed = %d%s",
                         super.toString(),
                         name,
                         brand,
                         maxSpeed,
                         data);
}

The implementation of toString() calls another toString method which takes a string as parameter. The toString(String) is the method which the child classes will overwrite. The toString() should not overwritten by them Therefore the toString() is made final.

The Car and the Truck class overwrite the toString(String) as follows:

public class Car extends Vehicle{
    private int seats;

    @Override
    public String toString(final String data) {
        return super.toString(String.format(", seats = %d%s", seats, data));
    }
}

public class Truck extends Vehicle {
    private int maxLoad;

    @Override
    public String toString(final String data) {
        return super.toString(String.format(", maxLoad = %d%s", maxLoad, data));
    }
}