0

看看这个简单的 Java 代码:

class A {
    public static void main(String[] args) {
        final int x;
        try {
            throw new RuntimeException();
            x = 1;
        } finally {}
        x = 2;
        System.out.println("x: " + x);
    }
}

我希望它打印“x:2”。

A.java:6: unreachable statement
            x = 1;
            ^
A.java:8: variable x might already have been assigned
        x = 2;
        ^
2 errors

它说它不会编译,因为在第 8 行,x = 2可能会重新分配最终变量,但这是错误的,因为如上所述,该行x = 1无法访问,因此它将第一次分配它,而不是重新分配。

为什么编译器在知道尚未分配时会给出错误说明“x 可能已被分配” x

4

6 回答 6

2

JLS第16章对此进行了解释

[...] 同样,每个空白的 final 变量最多只能分配一次;当对它进行分配时,它必须绝对未分配。

当且仅当变量的简单名称(或者,对于字段,其简单名称由此限定)出现在赋值运算符的左侧时,才定义这样的赋值。

对于每次对空白最终变量的赋值,该变量必须在赋值之前明确地未赋值,否则会发生编译时错误。

因此,JLS 似乎并不关心无法访问的代码。

关于例外情况,它说:

catch 子句(第 14.20 节)的异常参数 V 在 catch 子句的主体之前被明确分配(而且不是绝对未分配)。

所以这里的问题是,x=1并且x=2两者都被确定为

如果 try 语句确实有 finally 块,那么这些规则也适用:

V is definitely assigned after the try statement iff at least one of the following is true:

    V is definitely assigned after the try block and V is definitely assigned after every catch block in the try statement.

    V is definitely assigned after the finally block.

    V is definitely unassigned after a try statement iff V is definitely unassigned after the finally block.
于 2013-06-30T23:38:54.900 回答
0

java 编译器不能像人类一样看待事物。它看不到因果,只有错误。在这种情况下,这可能是一件好事,因为即使您修复了其中一个错误,另一个错误也会持续存在。

于 2013-06-30T23:32:28.110 回答
0

这可能是一个语言定义问题。如果可能已经分配,​​规范的一个区域禁止重新分配。另一个领域讨论了无法访问的代码。

两者的结合可能从未真正得到解决。

你能否提供一些更能代表你真正想要完成的东西?

于 2013-06-30T23:34:08.053 回答
0

看起来你正在学习 Java。第一个错误是因为编译器可以看到在您抛出异常后无法继续执行块:控制将跳转到捕获异常的任何地方。其他海报已经解释了第二个错误。

于 2013-07-01T00:05:11.063 回答
0

我见过其他不太直接的案例,例如:

final int x;
boolean b = ...;
if(b) {
   x = 1;
}
...
if(!b) {
   x = 2;
}

最简单的解决方案是分配给一个临时的非最终变量,然后将其复制到最终变量:

final int x;
int _x = 0;
boolean b = ...;
if(b) {
   _x = 1;
}
...
if(!b) {
   _x = 2;
}
x = _x;
于 2013-07-01T00:05:29.643 回答
0

第一个错误是由于无法访问的代码造成的。一旦抛出异常,该方法就会停止,并且永远无法执行下一行。您可以通过简单地从 x 中删除 final 修饰符来修复第二个错误。但我必须问,你为什么要编写一个唯一目的是抛出 RuntimeException 的程序?

于 2013-06-30T23:30:08.503 回答