Enum类型中wrt到构造函数的静态块的执行顺序

这来自Effective Java:

// Implementing a fromString method on an enum type private static final Map stringToEnum = new HashMap(); static { // Initialize map from constant name to enum constant for (Operation op : values()) stringToEnum.put(op.toString(), op); } // Returns Operation for string, or null if string is invalid public static Operation fromString(String symbol) { return stringToEnum.get(symbol); } 

请注意,Operation常量将从创建常量后运行的静态块放入stringToEnum映射中。 试图使每个常量从其自己的构造函数放入映射将导致编译错误。 这是一件好事,因为如果它是合法的,它会导致NullPointerException。 除编译时常量字段外,不允许枚举构造函数访问枚举的静态字段。 这种限制是必要的,因为在构造函数运行时尚未初始化这些静态字段。

我的问题是关于这条线:

“请注意,操作常量将从创建常量后运行的静态块放入stringToEnum映射中”。

我认为静态块在构造函数运行之前执行。 实际上是在类加载时执行的。

我在这里想念的是什么?

我理解你的问题是:为什么要保证在运行静态块之前初始化枚举常量。 答案在JLS中给出,具体的例子在#8.9.2.1中给出,其解释如下:

静态初始化从上到下发生。

枚举常量是隐式的最终静态,并在静态初始化程序块之前声明。

编辑

行为与普通类没有什么不同。 以下代码打印:

 In constructor: PLUS PLUS == null MINUS == null In constructor: MINUS PLUS != null MINUS == null In static initialiser PLUS != null MINUS != null In constructor: after static PLUS != null MINUS != null 
 public class Operation { private final static Operation PLUS = new Operation("PLUS"); private final static Operation MINUS = new Operation("MINUS"); static { System.out.println("In static initialiser"); System.out.print("PLUS = " + PLUS); System.out.println("\tMINUS = " + MINUS); } public Operation(String s) { System.out.println("In constructor: " + s); System.out.print("PLUS = " + PLUS); System.out.println("\tMINUS = " + MINUS); } public static void main(String[] args) { Operation afterStatic = new Operation ("after static"); } } 

Operation常量是在出现的顺序中在静态块中创建的静态字段。

 static { // instantiate enum instances here ... // Initialize map from constant name to enum constant for (Operation op : values()) stringToEnum.put(op.toString(), op); } 

当类加载器加载类时, static块按照外观顺序执行(可以有多个静态块),例如。 它在构造函数之前运行。