静态初始化程序由类加载器调用一次,这正是我想要的,但在静态代码块之外进行初始化更具可读性(有争议)。两者之间有区别吗?
private static final Map<MyEnum, Cheese> cheeseCache;
static {
parserCache = new EnumMap< MyEnum, String>(MyEnum.class){{
for(MyEnum myEnum: MyEnum.values()){
put(myEnum, new Cheese(myEnum)) ;
}
}};
}
或者这个:
private static final Map<Lab, LabResultParser> cheeseCache
= new EnumMap< MyEnum, String>(MyEnum.class){{
for(MyEnum myEnum: MyEnum.values()){
put(myEnum, new Cheese(myEnum)) ;
}
}};
答案 0 :(得分:3)
它会影响排序 - 例如你可以:
private static final int declaredFirst;
private static final int declaredSecond = new Random.nextInt();
static {
declaredFirst = declaredSecond + 1;
}
初始化程序以文本顺序执行。当然,您可能刚刚宣布declaredFirst
秒:
private static final int declaredSecond = new Random.nextInt();
private static final int declaredFirst = declaredSecond + 1;
我个人使用静态初始化块,我无法在单个表达式中干净地表达初始值。
哦,如果在静态初始化块中初始化,则不能将变量视为常量表达式:
private static final int THIS_IS_A_CONSTANT = 10;
private static final int thisIsNotAConstant;
static {
thisIsNotAConstant = 20;
}
public static void main(String[] args) {
System.out.println(THIS_IS_A_CONSTANT); // 10 is inlined
System.out.println(thisIsNotAConstant); // 20 is not inlined
}
当然,这只是很少相关。
所以在大多数案例中,这只是个人选择。当然在你的情况下,使用更多语句的能力意味着你不需要使用丑陋的(IMO)“匿名内部类来获得一些初始化”:
private static final Map<MyEnum, Cheese> cheeseCache;
static {
parserCache = new EnumMap<>(MyEnum.class);
for (MyEnum myEnum: MyEnum.values()) {
put(myEnum, new Cheese(myEnum));
}
}
答案 1 :(得分:1)
为了初始化,两个片段都会创建一个扩展EnumMap
的匿名内部类。简单地委托给一个方法会更简洁:
private static final Map<MyEnum, Cheese> CHEESE_CACHE = createCheeseCache();
private static Map<MyEnum, Cheese> createCheeseCache() {
EnumMap<MyEnum, Cheese> result = new EnumMap<MyEnum, Cheese>(MyEnum.class);
for (MyEnum myEnum: MyEnum.values()){
result.put(myEnum, new Cheese(myEnum)) ;
}
return result;
}
答案 2 :(得分:0)
在你的情况下没有区别,因为你没有做任何逻辑来决定应该为静态变量分配什么值。
声明中字段的初始化值适用于 初始化值可用,初始化可以 放在一条线上。但是,这种初始化形式存在局限性 因为它的简单。如果初始化需要一些逻辑(for 例如,错误处理或for循环来填充复杂的数组),简单 任务不充分。实例变量可以初始化 构造函数,可以使用错误处理或其他逻辑。至 为类变量提供相同的功能,即Java编程 语言包括静态初始化块。
但我会使用静态块,因为如果需要,您还可以选择try/catch
中的初始化代码。假设在填充enumMap时出现问题的情况,如果异常在逻辑上不是致命的,我可能仍希望继续执行。