views:

63

answers:

2

I have a static setter that is used to set all instances of MyClass:

public class MyClass {  
        ....
    protected static final Setter setter = new Setter();
        ...
}

However this does not compile since the setter constructor throws an exception:

public class Setter {

    public Setter() throws FileNotFoundException {
             ....
    }
}

How can I work around this?

+2  A: 

You can create it within a static function, as long as you catch the Exception it (potentially) raises.

public class MyClass {
    protected static final Setter setter = createSetter();

    protected static Setter createSetter() {
        try {
            return new Setter();
        } catch(FileNotFoundException e) {
            // handle it appropriately
            return null;
        }
    }
}

There is no way to allow the exception to propagate, since it raises a checked exception (and that's illegal during initialization). There's a couple ways to deal with that:

  • Raise an unchecked exception: This causes a java.lang.ExceptionInInitializerError to get raised when it tries to load the class. It can be confusing, and hard to trace and debug. I don't recommend it.

  • Change it to a non-final variable, and create a function to access it: If the variable's non-final, you can check if it's set in the get, and raise the checked exception if it's not. This allows (indeed, requires) your code to handle the exception at the point where it's called:


public class MyClass {
    private static Setter setter;

    protected static synchronized Setter getSetter() raises FileNotFoundException {
        if setter == null {
            setter = new Setter();
        }

        return setter;
    }
}
Chris B.
what if it is a fatal error and it should propagate?
sixtyfootersdude
@sixtyfootersdude: wrap it in an unchecked excpetion.
Michael Borgwardt
+5  A: 

The ExceptionInInitializerError is designed for exactly this purpose. Here's a cite of relevance from the linked Javadoc:

Signals that an unexpected exception has occurred in a static initializer. An ExceptionInInitializerError is thrown to indicate that an exception occurred during evaluation of a static initializer or the initializer for a static variable.

Wrap the assignment in a static initializer block and handle accordingly.

public class MyClass {  
    protected static final Setter setter;

    static {
        try { 
            setter = new Setter();
        } catch (FileNotFoundException e) {
            throw new ExceptionInInitializerError(e);
        }
    }
}
BalusC