1

This is my parent class with two methods named toString. The one with the parameter is used in the child class.

public abstract class Army {
    private String commander;
    private int soldiers;
    private int guns;
    private int horses;
    private int officers;
    // getters & setters
    public Army(){
    }

    @Override
    public String toString() {
        return "Army{" +
                "commander='" + commander + '\'' +
                ", soldiers=" + soldiers +
                ", guns=" + guns +
                ", horses=" + horses +
                ", officers=" + officers +
                '}';
    }

    public String toString(String type) {
        var result = toString();
        return result.replace("Army", type);
    }
}

This is my child class, where I am using the toString(String type)method from the parent class inside the toString method of the child class:

public class PanzerArmy extends Army {
    private String tanks = "tanks";

    public String getTanks() {
        return tanks;
    }

    public void setTanks(String tanks) {
        this.tanks = tanks;
    }

    @Override
    public String toString() {
        return super.toString("PanzerArmy") +
                " tanks='" + tanks + '\'' +
                '}';
    }
}

When I try to display object of child class I get this error:

Exception in thread "main" java.lang.StackOverflowError

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Monoxyd
  • 406
  • 1
  • 7
  • 18

1 Answers1

4

In Your PanzerArmy.toString() you call Army.toString(String), which in turn calls toString(). You might expect Army.toString() to be executed here, but since you overrode it in PanzerArmy (and the current object is of type PanzerArmy) it will call PanzerArmy.toString(). .. which will call Army.toString(String) and start the whole jazz again, in a never ending recursion. Eventually the JDK decides that it's got enough of this and bails.

A better solution would be to make the toString() in Army abstract and only implement toString(String).

Alternatively you could use something like getClass().getSimpleName() to get the short name of the current class and immediately use that instead of having to tweak toString() for each subclass.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • Another suitable solution can be to create an accessory method `_toString()` in `Army.class` that actually creates the string and handles all the operations that must be performed by every `toString` method and use it on the one overridden and on the adjunctive method. In this way, no recursion should happen. – Thecave3 May 21 '21 at 10:03