在 Java 中发生异常时为最终变量分配默认值

发布于 2024-08-28 08:31:30 字数 664 浏览 7 评论 0原文

为什么Java不允许我在try块中设置值后为catch块中的final变量赋值,即使在发生异常时不可能写入最终值。

这是一个演示该问题的示例:

public class FooBar {

    private final int foo;

    private FooBar() {
        try {
            int x = bla();
            foo = x; // In case of an exception this line is never reached
        } catch (Exception ex) {
            foo = 0; // But the compiler complains
                     // that foo might have been initialized
        }
    }

    private int bla() { // You can use any of the lines below, neither works
        // throw new RuntimeException();
        return 0;
    }
}

该问题并不难解决,但我想了解为什么编译器不接受此问题。

预先感谢您的任何意见!

Why won't Java let me assign a value to a final variable in a catch block after setting the value in the try block, even if it is not possible for the final value to be written in case of an exception.

Here is an example that demonstrates the problem:

public class FooBar {

    private final int foo;

    private FooBar() {
        try {
            int x = bla();
            foo = x; // In case of an exception this line is never reached
        } catch (Exception ex) {
            foo = 0; // But the compiler complains
                     // that foo might have been initialized
        }
    }

    private int bla() { // You can use any of the lines below, neither works
        // throw new RuntimeException();
        return 0;
    }
}

The problem is not hard to work around, but I would like to understand why the compiler does not accept this.

Thanks in advance for any inputs!

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

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

发布评论

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

评论(3

莫多说 2024-09-04 08:31:30
try {
    int x = bla();
    foo = x; // In case of an exception this line is never reached
} catch (Exception ex) {
    foo = 0; // But the compiler complains
             // that foo might have been initialized
}

原因是编译器无法推断异常只能在 foo 初始化之前抛出。这个例子是一个特殊情况,很明显这是正确的,但请考虑:

try {
    int x = bla();
    foo = x; // In case of an exception this line is never reached...or is it?
    callAnotherFunctionThatThrowsAnException();  // Now what?
} catch (Exception ex) {
    foo = 0; // But the compiler complains
             // that foo might have been initialized,
             // and now it is correct.
}

编写一个编译器来处理像这样的非常特殊的情况将是一项艰巨的任务 - 可能有很多这样的情况。

try {
    int x = bla();
    foo = x; // In case of an exception this line is never reached
} catch (Exception ex) {
    foo = 0; // But the compiler complains
             // that foo might have been initialized
}

The reason is because the compiler cannot infer that the exception can only be thrown before foo is initalized. This example is a special case where it is obvious that that is true, but consider:

try {
    int x = bla();
    foo = x; // In case of an exception this line is never reached...or is it?
    callAnotherFunctionThatThrowsAnException();  // Now what?
} catch (Exception ex) {
    foo = 0; // But the compiler complains
             // that foo might have been initialized,
             // and now it is correct.
}

To write a compiler to handle very specific cases like this would be an immense task - there are likely very many of them.

寂寞美少年 2024-09-04 08:31:30

作为一个学究,Thread.stop(Throwable) 可能会在 try 块分配后立即抛出异常。

然而,具有明确指派和相关术语的规则足够复杂。检查 JLS。尝试添加更多规则会使语言变得复杂并且不会带来显着的好处。

To be a pedant, Thread.stop(Throwable) could throw an exception immediately after the try block assignment.

However, the rules with definite assignment and allied terms are complex enough. Check the JLS. Trying to add more rules would complicate the language and not provide significant benefit.

四叶草在未来唯美盛开 2024-09-04 08:31:30

抛出错误怎么样?

How about a thrown Error?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文