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
块按照外观顺序执行(可以有多个静态块),例如。 它在构造函数之前运行。