Instance Initialiser中的StackOverflowError

Rak*_*ury 4 java theory

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

public class Test {

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

    {
        System.out.println("Instance execution");
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

它给了我这个错误:

Exception in thread "main" java.lang.StackOverflowError
at Test.<init>(Test.java:15)
Run Code Online (Sandbox Code Playgroud)

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

T.J*_*der 6

这个:

{
    Test test = new Test();
    test.anotherMethod();
}
Run Code Online (Sandbox Code Playgroud)

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

它是抛出此错误的构造函数吗?

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

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

不确定"系统方法"是什么意思,但问题是初始化程序块是按实例运行的.如果你想在类初始化时只运行一次,你可以使用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();
    }
}
Run Code Online (Sandbox Code Playgroud)

那输出:

Class initialization
Instance execution
Method execution
Instance execution

(我们看到"实例执行"两次,因为有一个new Test在初始化块中main,另一个在static初始化块中.)

但实际上,最简单的方法是将呼叫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");
    }
}
Run Code Online (Sandbox Code Playgroud)

哪个输出

Instance execution
Method execution

  • @RakaChowdhury:你的字面意思是"实时"还是"真实"?我没有Java的实时编程经验(而且我的C经验也不相关,而且无论如何都已经过时了).但是,如果你的意思是"真实的",我的建议是:尽可能缩短实例初始化程序,但不能缩短.它们基本上是构造函数代码,并且构造函数通常应该(再次)尽可能短,但不能更短.:-) (2认同)