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

3 回答 3

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));
    }
}
于 2013-08-24T11:01:02.653 回答
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;
}
于 2013-08-24T11:02:26.170 回答
0

在您的情况下没有区别,因为您没有做任何逻辑来决定应该为静态变量分配什么值。

java教程

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

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

于 2013-08-24T10:57:43.760 回答