Monday, February 21, 2011

Java - Can final variables be initialized in static initialization block?

Upto my theoretical knowledge, static variables can be initialized in static initialization block.

But when I tried to implement the above (static variables that are final too), I got an error as showing in the below snapshot.

Sanpshot can directly be accessed at http://i49.tinypic.com/5vxfn4.jpg (in case it is not clear in the below size).

From stackoverflow
  • Yes of course: static final can be initialized in a static block but.... You have GOTOs in that example (that you don't see but the try/catch is basically a 'GOTO catch if something bad happens').

    If an exception is thrown, subsequent final variables shall not be initialized.

    Note that overall static fly against the logic of OO and make the OO purists want to cry.

    From a more 'down to earth' point of view it shall undoubtly complicate your testing as well as make debugging harder.

    Yatendra Goel : Can I throw exception from `static initialization block`. What can I do when a code in `static initialization block` throw some exception which I don't want to handle.
    awk : you can initialize the variables outside of the try catch block, e.g. doing the exception throwing code in try catch and initializing in finally...
    Kevin Brock : @awk: he would need to use locals to do the assignment if the exception throwing code is the getString(...) method call.
    awk : @Kevin of course, the final variables have to be assigned to something, so in the catch block he would probably assign it to null
  • You can do this but you need to exit the static block by throwing an exception - you can rethrow the exception that was caught or a new one. Generally this exception must be a RuntimeException. You really should not catch a generic Exception but more specific exception(s) that might be thrown from within your try block. Finally, if a static initializer throws an exception then it will render the class unusable during that specific run because the JVM will only attempt to initialize your class once. Subsequent attempts to use this class will result in another exception, such as NoClassDefFoundError.

    So, to work, your initializer should read something like this:

    static {
        try {
            ...
        } catch (Exception e) {
            e.PrintStackTrace();
            throw new InitializationFailedException("Could not init class.", e);
        }
    }
    

    Assuming that InitializationFailedException is a custom RuntimeException, but you could use an existing one.

    Kevin Brock : Not sure why there was a down vote, please explain.

0 comments:

Post a Comment