研究此代码:
public class TestFinalAndCatch {
private final int i;
TestFinalAndCatch(String[] args) {
try {
i = method1();
} catch (IOException ex) {
i = 0; // error: variable i might already have been assigned
}
}
static int method1() throws IOException {
return 1;
}
}
编译器说java: variable i might already have been assigned
但对我来说,这似乎是不可能的情况。
答案 0 :(得分:8)
i
是最终版,因此只能分配一次。编译器可能不够聪明,无法实现如果抛出异常,则不会发生第一个赋值,如果不抛出异常,则不会发生第二个赋值。
答案 1 :(得分:8)
问题在于,在这种情况下,编译器基于语法而不是基于语义的。 有2种解决方法: 首先根据方法移动异常句柄:
package com.java.se.stackoverflow;
public class TestFinalAndCatch {
private final int i;
TestFinalAndCatch(String[] args) {
i = method1();
}
static int method1() {
try {
return 1;
} catch (Exception ex) {
return 0;
}
}
}
第二个基于使用temporar变量:
package com.java.se.stackoverflow;
import java.io.IOException;
public class TestFinalAndCatch {
private final int i;
TestFinalAndCatch(String[] args) {
int tempI;
try {
tempI = method1();
} catch (IOException ex) {
tempI = 0;
}
i = tempI;
}
static int method1() throws IOException {
return 1;
}
}
答案 2 :(得分:0)
要解决此问题,请在try catch块中使用局部变量,然后将该结果分配给实例变量。
public class TestFinalAndCatch {
private final int i;
TestFinalAndCatch(String[] args) {
int tmp;
try {
tmp = method1();
} catch (IOException ex) {
tmp = 0;
}
i = tmp;
}
static int method1() throws IOException {
return 1;
}
}
答案 3 :(得分:0)
看起来像JDK bug。现在状态 - 固定。但我无法找到哪个版本。