繁体   English   中英

在自己的静态初始化程序中创建类的对象

[英]Creating an object of a class in its own static initializer

根据JLS

类或接口类型T将在第一次出现以下任何一个之前立即初始化

T是一个类,并且创建了T的实例。

它也说,

类的初始化包括执行其静态初始化程序和类中声明的静态字段(类变量)的初始化程序

我从中推断出两点

  • 类初始化包括执行其静态初始化器
  • 如果实例化类,则会发生类初始化。

现在,

我假设当我在自己的(Test自己的)静态初始化程序中创建一个类Test的对象时,它应该抛出一个堆栈溢出,因为它应该重复调用自身,因为根据上面两点,类的实例化应该初始化类和初始化块具有类的实例化。 当我在自己的构造函数或其自己的实例初始化程序中实例化类时,会发生堆栈溢出。

例如,

public class Test {

    static{
        System.out.println("static test");
        new Test();
    }
    {
       //new Test(); // This will give a stack overflow
        System.out.println("intializer");
    }

    public Test(){
        //new Test(); // This will give a stack overflow
        System.out.println("constructor");
    }
    public static void main(String[] args) {
    }

}

然而,结果是不同的。

结果:

静态测试初始化​​构造函数

要么我太困惑了解课程的初始化,要么如果我在这里遗漏一些非常明显的东西并且感谢你的帮助,我会道歉。

JLS第12.4.2节中指定的类初始化过程的第3步是

如果C的Class对象指示当前线程正在为C进行初始化,那么这必须是初始化的递归请求。 释放LC并正常完成。

在其静态初始化程序中创建类的实例不会递归地重新初始化该类; 检测到初始化的递归请求,并且不执行任何操作。

(注意,“正常完成”意味着“操作完成”,而不是“按照通常遵循的步骤完成操作”;它与“完全突然完成”相反,这意味着我们遇到某种异常或错误。)

只有在加载类时才会调用静态初始值设定项。 在静态初始值设定项中实例化对象不会导致类再次加载,类的类加载只发生一次,类加载器将该类缓存为JVM实例的生命周期。

如果您在实例初始化程序或构造函数中创建了一个新实例,那么您将收到stackoverflow错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM