Java双支撑初始化工作总是如何?

use*_*958 15 java initializer double-brace-initialize

我知道这段代码:

Set<String> set = new HashSet<String>() {{
  add("test1");
  add("test2");
}};
Run Code Online (Sandbox Code Playgroud)

是真的:

Set<String> set = new HashSet<String>() {
  {//initializer
    add("test1");
    add("test2");
  }
};
Run Code Online (Sandbox Code Playgroud)

初始化程序块正在构造函数块之前执行.在上面的示例中,在执行构造函数之前调用add("test1").构造函数可能正在初始化许多实例字段,因此这个类可以工作.我想知道为什么在构造函数之前调用.add()会起作用?有没有导致问题的案例?

Sam*_*ard 17

你遗漏了一个细节解释了这一点.

首先,让我们回顾一下初始化过程的第3步到第5 (总结):

3.调用超类构造函数
4. 调用实例初始值设定项
5.调用构造函数的主体

你遗漏的细节是你的表达式不是简单地创建一个新的HashSet类实例,它实际上是创建一个匿名子类的新实例HashSet.(我相信这在第15.9.1节中有详细说明.)

由于您未声明构造函数,因此使用默认构造函数.但在此之前,超类的构造函数HashSet已经完成.

因此,总之,HashSet构造函数在初始化程序块运行之前完成.


mpr*_*vat 6

这个假设是错误的:

初始化程序块正在构造函数块之前执行.

因为在这种特殊情况下,初始化程序块构造函数块的一部分.

文档境界清楚,

Java编译器将初始化程序块复制到每个构造函数中.因此,该方法可用于在多个构造函数之间共享代码块.

我认为你对静态初始化器感到困惑.