在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,但我可能错了)。