What is the best way to initialize a complex static member in Java?

限于喜欢 提交于 2019-12-05 06:47:33

问题


My objective is to have a private static Properties object in my class, to act as defaults when creating other Properties objects needed by my application. The current implementation looks like this:

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

Looking at it, it works, but it doesn't feel right.

How would you do it?


回答1:


There are basically two ways. First way is using the static block as you have shown (but then with an ExceptionInInitializerError instead of the RuntimeException). Second way is using a static method which you call immediately on declaration:

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

The ConfigurationException can just be your custom class extending RuntimeException.

I personally prefer the static block because it doesn't make sense having a method which is executed only once ever in its life. But if you refactor the method so that it takes a filename and can be reused globally, then that would be more preferred.

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



回答2:


Instead of a generic RuntimeException, I would throw an ExceptionInInitializerError, which is ment for exacctly this purpose. From the API documentation: "Signals that an unexpected exception has occurred in a static initializer."




回答3:


Seems acceptable to me; load in the static initialiser, it gets called only when the class is referenced, and is only called once. I like it. The only thing I'd do is make it final.

Well, aside from the exception. I'd try and avoid that somehow (I have in the back of my mind that you should avoid exceptions in those types of initialisers, but I could be wrong on that).



来源:https://stackoverflow.com/questions/2027244/what-is-the-best-way-to-initialize-a-complex-static-member-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!