将Enum类型wrt中的静态块的执行顺序传递给构造函数
这来自Effective Java:
// Implementing a fromString method on an enum type
private static final Map<String, Operation> stringToEnum
= new HashMap<String, Operation>();
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);
}
请注意,操作常量从创建常量后运行的静态块放入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
块按照外观顺序执行(可以有多个静态块),例如。 它在构造函数之前运行。
上一篇: Execution order of of static blocks in an Enum type w.r.t to constructor