45

Based on my understanding of the Java language, static variables can be initialized in static initialization block.

However, when I try to implement this in practice (static variables that are final too), I get the error shown in the screenshot below:

https://i.stack.imgur.com/5I0am.jpg

4

4 回答 4

38

Yes of course: static final variables can be initialized in a static block but.... you have implicit GOTOs in that example (try/catch is essentially a 'GOTO catch if something bad happens').

If an exception is thrown your final variables will not be initialized.

Note that the use of static constructs goes against Object-Oriented dogma. It may complicate your testing and make debugging more difficult.

于 2010-02-26T06:50:58.833 回答
20

您可以这样做,但您需要通过抛出异常来退出静态块 - 您可以重新抛出已捕获的异常或新异常。通常,此异常必须是RuntimeException. 您真的不应该捕获Exception可能从您的try块中抛出的通用但更具体的异常。最后,如果静态初始化程序抛出异常,那么它将在特定运行期间使该类不可用,因为 JVM 只会尝试初始化您的类一次。后续尝试使用此类将导致另一个异常,例如NoClassDefFoundError.

所以,为了工作,你的初始化程序应该是这样的:

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

假设这InitializationFailedException是一个 custom RuntimeException,但您可以使用现有的。

于 2010-02-26T07:02:04.600 回答
9
public class MyClass
{
    private static final SomeClass myVar;

    static
    {
        Object obj = null;  // You could use SomeClass, but I like Object so you can reuse it
        try
        {
            obj = new SomeClass(...);    
        }
        catch(WhateverException err)
        {
            // Possibly nested try-catches here if the first exception is recoverable...
            // Print an error, log the error, do something with the error
            throw new ExceptionInInitializerError(err); 
        }
        finally
        {
            myVar = (SomeClass) obj;
        }
    }
}

假设上游无法捕获ExceptionInInitializationError或一般异常,则程序不应尝试使用myVar。但是,如果这些被捕获并且程序没有结束,那么您需要编写代码来监视和处理myVar是否为空(或者对全部结束感到满意NullPointerExceptions)。

我不确定有没有好方法来处理这个问题。

于 2011-11-28T17:01:24.553 回答
0

您可以将声明放在 finally 块中吗?

try {
    //load file
} catch(IOException e) {
    // horay
} finally {
    HOST=config.get......
}
于 2011-03-20T16:35:42.087 回答