在Java中初始化复杂静态成员的最佳方法是什么?

我的目标是在我的类中有一个私有静态Properties对象,在创建我的应用程序所需的其他Properties对象时充当默认值。 当前的实现如下所示:

 public class MyClass { private static Properties DEFAULT_PROPERTIES = new Properties(); static { try { DEFAULT_PROPERTIES.load( MyClass.class.getResourceAsStream("myclass.properties")); } catch (IOException e) { throw new RuntimeException(e); } } } 

看着它,它有效,但感觉不对。

你会怎么做?

基本上有两种方式。 第一种方法是使用正如您所示的静态块(但随后使用ExceptionInInitializerError而不是RuntimeException )。 第二种方法是使用静态方法,您可以在声明时立即调用:

 private static Properties DEFAULT_PROPERTIES = getDefaultProperties(); private static Properties getDefaultProperties() { Properties properties = new Properties(); try { properties.load(MyClass.class.getResourceAsStream("myclass.properties")); } catch (IOException e) { throw new ConfigurationException("Cannot load properties file", e); } return properties; } 

ConfigurationException可以是扩展RuntimeException的自定义类。

我个人更喜欢static块,因为拥有一个在其生命中执行过一次的方法是没有意义的。 但是如果你重构方法以便它采用文件名并且可以全局重用,那么这将是更优选的。

 private static Properties DEFAULT_PROPERTIES = SomeUtil.getProperties("myclass.properties"); // Put this in a SomeUtil class. public static Properties getProperties(String filename) { Properties properties = new Properties(); try { properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(filename)); } catch (IOException e) { throw new ConfigurationException("Cannot load " + filename, e); } return properties; } 

我会抛出一个ExceptionInInitializerError而不是通用的RuntimeException,这是为了达到这个目的。 从API文档:“表示静态初始化程序中发生了意外exception。”

我似乎可以接受; 在静态初始化器中加载,只有在引用类时才会调用它,并且只调用一次。 我喜欢。 我唯一要做的就是让它成为final

好吧,除了例外。 我试着以某种方式避免这种情况(在我的脑海中,我应该避免在这些类型的初始化程序中出现exception,但我可能错了)。