Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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."

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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top