Java - 最终变量可以在静态初始化块中初始化吗?

时间:2010-02-26 06:47:38

标签: java static final

根据我对Java语言的理解,可以在static initialization block中初始化静态变量。

但是,当我尝试在实践中实现这一点时(static变量final也是如此),我会得到以下屏幕截图中显示的错误:

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

4 个答案:

答案 0 :(得分:35)

是的当然可以:static final变量可以在静态块中初始化,但是 ....在该示例中你有隐式GOTO(try/catch本质上是'GOTO捕获,如果发生了不好的事情')。

如果抛出异常,您的final变量将不会被初始化。

请注意,静态构造的使用违背了面向对象的教条。它可能会使您的测试复杂化并使调试变得更加困难。

答案 1 :(得分:18)

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

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

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

假设InitializationFailedException是自定义RuntimeException,但您可以使用现有的。{/ p>

答案 2 :(得分: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全部出来感到满意)。< / p>

我不确定有什么好方法可以解决这个问题。

答案 3 :(得分:0)

你能把声明放在finally块吗?

try {
    //load file
} catch(IOException e) {
    // horay
} finally {
    HOST=config.get......
}