【问题标题】:Why do I get StackOverflowError [duplicate]为什么我会收到 StackOverflowError [重复]
【发布时间】:2021-08-10 13:05:25
【问题描述】:

这是我的父类,有两个名为toString 的方法。带参数的那个用在子类中。

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);
    }
}

这是我的子类,我在子类的 toString 方法中使用父类中的 toString(String type) 方法:

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 + '\'' +
                '}';
    }
}

当我尝试显示子类的对象时出现此错误:

线程“主”java.lang.StackOverflowError 中的异常

【问题讨论】:

  • 你在toString方法中进行了递归。

标签: java stack-overflow infinite-loop tostring


【解决方案1】:

在您的PanzerArmy.toString() 中,您调用Army.toString(String),而后者又调用toString()。您可能希望Army.toString() 在这里执行,但由于您在PanzerArmy 中覆盖了它(并且当前对象的类型为PanzerArmy),它将调用PanzerArmy.toString()。 .. 这将调用Army.toString(String) 并以永无止境的递归再次启动整个爵士乐。最终,JDK 决定它已经受够了这个并放弃了。

更好的解决方案是将Army 中的toString() 抽象化,实现toString(String)

或者,您可以使用 getClass().getSimpleName() 之类的东西来获取当前类的短名称并立即使用它,而不必为每个子类调整 toString()

【讨论】:

  • 另一种合适的解决方案是在Army.class 中创建一个辅助方法_toString(),它实际创建字符串并处理每个toString 方法必须执行的所有操作,并在一个被覆盖和附加的方法。这样,就不会发生递归了。
猜你喜欢
  • 1970-01-01
  • 2017-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多