java - 在自己的静态初始化器中创建类的对象

标签 java static language-lawyer

根据 JLS :

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

T is a class and an instance of T is created.

它还说,

Initialization of a class consists of executing its static initializers and the initializers for static fields (class variables) declared in the class

由此我推断出两点

  • 类初始化包括执行其静态初始化器
  • 类初始化发生在类被实例化时。

现在,

我假设当我在它自己的(测试自己的)静态初始化器中创建一个类测试的对象时,它应该抛出一个堆栈溢出,因为它应该重复调用自己,因为根据以上两点,类的实例化应该初始化类和初始化 block 具有类的实例化。 当我在它自己的构造函数或它自己的实例初始值设定项中实例化类时发生堆栈溢出。

例如,

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

}

然而结果却有所不同。

结果:

static test intializer constructor

要么我对类的初始化理解太困惑,要么如果我在这里遗漏了一些非常明显的东西,我深表歉意,感谢您的帮助。

最佳答案

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

If the Class object for C indicates that initialization is in progress for C by the current thread, then this must be a recursive request for initialization. Release LC and complete normally.

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

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

关于java - 在自己的静态初始化器中创建类的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31508001/

相关文章:

java - Clojure JUNG setVertexFillPaintTransformer

java - JAR 文件是什么时候首次创建的?

java - 如何在不将方法设为静态的情况下使用@Enclosed

c# - 尝试通过属性默认值更改关系时发生意外的InvalidOperationException

c++ - 如何确定作业的两个副作用是否未排序?

java - 为什么在Java中的文件输入输出代码中出现一些错误?

java - 不确定如何使用 swing 绘制矩形

java - 同一jvm中两个应用程序的静态变量冲突

c - "char s[static 10]"等函数的数组参数中 static 关键字的用途是什么?

c++ - std::string::npos == -1 总是为真吗?