5

在学习 Java 认证测试时,我了解到静态初始化块在加载类时运行一次,按照在源代码中出现的顺序,实例初始化块在每次创建实例时运行,而构造函数中的代码每次运行之后创建一个实例。为了测试我创建了一个带有一些静态和实例初始化块的类以及一个带有打印内容的构造函数。一切都按预期工作——除了我认为“加载”只是在运行时,但我猜它会在创建第一个实例时发生,因为除非我创建至少一个类的实例,否则我根本不会得到任何输出。然后我用枚举尝试了同样的操作,订单全部关闭。首先,初始化块在代码中第一次引用枚举时为枚举所具有的每个值运行一次,其次——标记为静态的初始化块在我认为是实例初始化块之后运行!这与我的预期相反。这是我的问题的细分。

  1. 为什么标记为静态的初始化块在枚举中最后运行?
  2. 枚举可以有实例初始化块吗?
  3. 为什么我认为是实例初始化块的块在加载枚举时只运行一次,而不是每次引用新的枚举值时?
  4. 类静态初始化块在“加载”类时运行。加载是什么意思?在类中实例化对象时是否只发生一次?

谢谢!这让我很困惑。

public class EnumInit {
public static void main(String[] args) {
    System.out.println(Color.RED.toString() + " Main");
    MyInit myInit = new MyInit();
    System.out.println(Color.BLUE.toString() + " Main");
    MyInit mySecondInit = new MyInit();

}
}

enum Color {    
RED, BLUE, GREEN;
String instanceVar = "Enum Instance Variable Text";
static { System.out.println("Enum Static init block 1"); }
{ System.out.println("Enum Instance init block 1"); }
static { System.out.println("Enum Static static init block 2"); }
Color() { 
    System.out.println(instanceVar);
    System.out.println("Enum String Literal"); 
}
{ System.out.println("Enum Instance init block 2"); }   
}

class MyInit {
String instanceVar = "Class Instance Variable Text";
static { System.out.println("Class Static init block 1"); }
{ System.out.println("Class Instance init block 1"); }
static { System.out.println("Class Static static init block 2"); }
MyInit() { 
    System.out.println(instanceVar);
    System.out.println("Class String Literal"); 
}
{ System.out.println("Class Instance init block 2"); }  
}
4

2 回答 2

8

Java 语言规范对常量进行了说明enum

除了枚举类型 E 从 Enum 继承的成员之外, 对于每个声明的名称为 n 的枚举常量,该枚举类型都有一个隐式声明的名为 n 的类型 E 的 public static final 字段。这些字段被认为是在与相应的枚举常量相同的顺序,在枚举类型中显式声明的任何静态字段之前。每个这样的字段都被初始化为与之对应的枚举常量。

所以

enum Color {    
    RED, BLUE, GREEN;
    ...
}

实际上是

public static final Color RED = new Color();
public static final Color BLUE = new Color();
public static final Color GREEN = new Color();

static这将在你拥有的块之前得到评估。

为什么标记为静态的初始化块在枚举中最后运行?

往上看。

枚举可以有实例初始化块吗?

是的,编译你的代码,你会看到。

为什么我认为是实例初始化块的块在加载枚举时只运行一次,而不是每次引用新的枚举值时?

一旦枚举类型被初始化,枚举常量就会被创建(实例化)。你不会在enum任何时候创造一个新的

Color color = Color.RED;

您只是在引用一个已经创建的现有对象。

类静态初始化块在“加载”类时运行。加载是什么意思?在类中实例化对象时是否只发生一次?

当一个类在 JVM 中第一次被引用时,它会被 JVM 加载ClassLoader并初始化。在此处阅读更多相关信息。

于 2013-12-16T20:14:03.567 回答
0

enum最后static init block执行。

Enums
    1st  - instance init block 
    2nd  - constructor block
    last - static init block or any other declared static (only once and will be always last executed)

Classes
    1st - static init block or any other declared static (only once, always first to be executed)
    2nd - instance init block
    3rd - constructor
于 2021-12-21T03:48:49.573 回答