8

为什么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;
    }
}

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

提前感谢您的任何投入!

4

3 回答 3

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

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

于 2010-04-08T21:03:49.933 回答
2

作为一个书呆子,Thread.stop(Throwable)可以在 try 块分配之后立即抛出异常。

但是,具有明确分配和相关术语的规则已经足够复杂了。检查 JLS。尝试添加更多规则会使语言复杂化并且不会提供显着的好处。

于 2010-04-08T22:17:33.893 回答
0

扔了Error怎么办?

于 2010-04-08T20:45:58.833 回答