2013-08-24 31 views
1

静态初始化器由类加载器调用一次,这正是我想要的,但是在静态代码块之外进行初始化更具可读性(可辩论)。两者有什么不同?初始化变量与其声明或静态初始化之间有区别吗?

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

只是好奇,第二个编译?变量声明中的for循环? –

+0

@JunedAhsan是它在一个anoymous子类(双大括号initalziation) – NimChimpsky

+1

使用javap来拆卸这两个,看看它们有何不同。 –

回答

0

你的情况是没有区别的,你没有做任何的逻辑来决定什么样的价值应该被分配到静态变量。

java tutorial

在其声明中的字段值初始化时效果不错 初始化值可用并且初始化可以 放在同一行。但是,这种初始化形式由于其简单性而具有局限性 。如果初始化需要一些逻辑(例如,对于 示例,错误处理或for循环来填充复杂数组),简单的 赋值是不充分的。实例变量可以在 构造函数中初始化,其中可以使用错误处理或其他逻辑。对于 为类变量提供相同的功能,Java编程 语言包括静态初始化块。

但是我会和静态块一起去,因为如果需要,你将有一个额外的选项来围绕你的初始化代码在try/catch。假设在填充enumMap时出现问题的场景,如果异常不是逻辑上致命的,我仍然希望执行继续。

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)); 
    } 
} 
+0

噢,亲爱的。不知道最后一部分。 +1。 –

+0

@RohitJain:我没有想到它,直到我正在写答案:) –

+0

OOPs,最后一部分现在成为第二个最后部分。那个谈论常量的人。 –

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; 
}