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

Yat*_*oel 44 java static final

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

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

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

Syn*_*r0r 36

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

如果抛出异常,则final不会初始化变量.

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

  • `e.printStackTrace()`在catch块中本身让我哭泣. (5认同)
  • @awk:如果异常抛出代码是getString(...)方法调用,他将需要使用locals来进行赋值. (3认同)
  • 在退出静态块之前,需要确保初始化最终的静态变量.在您的情况下,也可以在catch块中初始化它们,或者根据您的要求更好地使用finally块 (3认同)
  • @Kevin当然,最终的变量必须分配给某个东西,所以在catch块中他可能会将它赋值为null (2认同)

Kev*_*ock 18

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

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

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

假设这InitializationFailedException是一个自定义RuntimeException,但你可以使用现有的.


小智 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

假设没有上游位置可以捕获ExceptionInInitializationError或一般异常,那么程序不应该尝试使用myVar.然而,如果这些被捕获并且程序没有结束,那么你需要编写代码来监视和处理myVar为空(或者对于NullPointerExceptions全部出来感到满意).

我不确定有一个很好的方法来处理这个问题.

  • >>> _然后你需要编写代码来监视和处理 myVar 是否为 null_ 这里静态初始化程序会抛出一个异常,该异常会阻止类被加载(因此变量不能在未初始化的情况下被引用),因此无需担心 NPE(空指针异常) (2认同)