为什么堆栈溢出错误会在初始化中出现

时间:2018-10-04 09:01:13

标签: java initialization stack-overflow

我有一个由于发生不可控制的递归而导致堆栈溢出问题的代码

public class Flaw {

    Flaw() {
        System.out.println("There");
    }

    Flaw obj = new Flaw();

    public static void main(String[] args) {
        new Flaw();
        System.out.println("Hi");
    }

}

有人可以向我解释为什么Flaw()构造函数不打印任何内容吗?

2 个答案:

答案 0 :(得分:5)

在可以执行Flaw构造函数的主体(将执行println语句)之前,请初始化类的实例变量。在您的情况下,这意味着Flaw obj=new Flaw();变量,它将创建另一个Flaw实例,触发另一个构造函数调用,依此类推...

无限的构造函数调用链导致StackOverflowError

答案 1 :(得分:1)

此:

public class Flaw {

    Flaw() {
        System.out.println("There");
    }

    Flaw obj = new Flaw();
}

与此相同:

public class Flaw {

    Flaw() {
        System.out.println("There");
    }

    Flaw obj;

    {
      obj = new Flaw();
    }
}

实例初始化程序插入在超类的构造函数的调用与构造函数主体的其余部分之间。因此,它等效于此:

public class Flaw {
    Flaw obj;

    Flaw() {
        // Invocation of superclass constructor.
        super();

        // Inlined instance initializer.
        obj = new Flaw();

        // Rest of constructor body.
        System.out.println("There");
    }
}

在打印任何内容之前,您需要从Flaw的构造函数中调用Flaw的构造函数。这就调用了Flaw的构造函数,后者又调用了Flaw的构造函数,而后者又调用了Flaw的构造函数,例如。