Instance Initialiser中的StackOverflowError

时间:2017-04-10 17:32:09

标签: java theory

这个问题更具理论性。所以我有以下一组代码:

public class Test {

    public static void main(String[] args) {
        Test test = new Test();
    }

    {
        System.out.println("Instance execution");
    }
}

它编译并打印“实例执行”。 但是当我尝试以这种方式执行其他方法时:

public class Test {

    public static void main(String[] args) {
        Test test = new Test();
    }

    {
        System.out.println("Instance execution");
    }

    private void anotherMethod() {
        System.out.println("Method execution");
    }

    {
        Test test = new Test();
        test.anotherMethod();
    }
}

它给了我这个错误:

Exception in thread "main" java.lang.StackOverflowError
at Test.<init>(Test.java:15)

我完全相信这个错误有最简单的解释,但我的问题是,构造函数是否抛出此错误?或者只有系统方法可以这样执行?可执行Instance Initialiser的整个方法对我来说都是新的,所以任何帮助都会非常感激。感谢。

2 个答案:

答案 0 :(得分:6)

此:

{
    Test test = new Test();
    test.anotherMethod();
}

是一个实例初始化块。它在每次创建Test实例时运行。在其中,您将...创建一个新的Test实例,该实例会自然地触发该块,然后创建一个新的Test实例,触发该块...您明白了

  

构造函数是否会抛出此错误?

它的实例初始化,是的。事实上,在封面下,编译器处理实例初始化程序块的方式是将该代码逐字地复制到类中每个构造函数的开头(包括默认代码,如果你不提供默认代码) ),在调用super之后(默认情况下,如果没有明确的话)。所以你可以说它是构造函数抛出错误,即使概念,它的实例初始化与构造函数本身不同。

  

或者只有System方法可以这样执行?

不确定你的意思&#34;系统方法,&#34;但问题是初始化程序块是按实例运行的。如果您只想在类初始化时运行一次,则可以使用 static 初始化程序块:

public class Test {

    public static void main(String[] args) {
        Test test = new Test();
    }

    {
        System.out.println("Instance execution");
    }

    private void anotherMethod() {
        System.out.println("Method execution");
    }

    static // <==================
    {
        System.out.println("Class initialization"); // ***
        Test test = new Test();
        test.anotherMethod();
    }
}

输出:

Class initialization
Instance execution
Method execution
Instance execution

(我们看到&#34;实例执行&#34;两次,因为new Test中有一个mainstatic初始化程序块中有另一个anotherMethod。 )

但实际上,最简单的方法就是将main中的public class Test { public static void main(String[] args) { Test test = new Test(); test.anotherMethod(); } { System.out.println("Instance execution"); } private void anotherMethod() { System.out.println("Method execution"); } } 拨打电话:

char *pdev[64];

输出

Instance execution
Method execution

答案 1 :(得分:1)

问题是,您在构造函数中创建了一个Test obejct,它将创建另一个Test对象,依此类推。而是使用

this.anotherMethod();