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

发布于 2024-08-22 15:24:50 字数 305 浏览 10 评论 0原文

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

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

https://i.sstatic.net /5I0am.jpg

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.sstatic.net/5I0am.jpg

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

药祭#氼 2024-08-29 15:24:50

当然是的:static final 变量可以在静态块中初始化但是....在该示例中您有隐式 GOTO(try/catch 本质上是一个“如果发生不好的事情则转到捕获”)。

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

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

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.

鲜血染红嫁衣 2024-08-29 15:24:50

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

因此,要正常工作,您的初始化程序应读取如下内容:

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

假设 InitializationFailedException 是自定义 RuntimeException,但您可以使用现有的异常。

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.

丶情人眼里出诗心の 2024-08-29 15:24:50
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 感到满意) )。

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

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;
        }
    }
}

Assuming no where upstream is in a position to catch either an ExceptionInInitializationError or a general Exception then the program should not ever try to use myVar. If however those are caught and the program doesn't end, then you need to code to watch for and handle myVar being null (or be happy with NullPointerExceptions coming out all over).

I'm not sure there is a good way to handle this.

甜心小果奶 2024-08-29 15:24:50

你能把声明放在finally块中吗?

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

Can you put the declaration in the finally block?

try {
    //load file
} catch(IOException e) {
    // horay
} finally {
    HOST=config.get......
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文