这来自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);
}
Run Code Online (Sandbox Code Playgroud)
请注意,Operation常量将从创建常量后运行的静态块放入stringToEnum映射中.试图使每个常量从其自己的构造函数放入映射将导致编译错误.这是一件好事,因为如果它是合法的,它会导致NullPointerException.除编译时常量字段外,不允许枚举构造函数访问枚举的静态字段.这种限制是必要的,因为在构造函数运行时尚未初始化这些静态字段.
我的问题是关于这条线:
"请注意,操作常量将从创建常量后运行的静态块放入stringToEnum映射中".
我认为静态块在构造函数运行之前执行.实际上是在类加载时执行的.
我在这里错过了什么?
ass*_*ias 13
我理解你的问题是:为什么要保证在运行静态块之前初始化枚举常量.答案在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
Run Code Online (Sandbox Code Playgroud)
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");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4532 次 |
| 最近记录: |