Почему Java не позволит мне присвоить значение последней переменной в блоке выгоды после устанавливания значения в блоке попытки, даже если для окончательного значения не будет возможно быть записанным в случае исключения.
Вот пример, который демонстрирует проблему:
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;
}
}
Проблема не трудна работать вокруг, но я хотел бы понять, почему компилятор не принимает это.
Заранее спасибо за любые исходные данные!
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.
}
Написать компилятор для обработки очень специфических случаев, подобных этому, было бы огромной задачей - их, вероятно, очень много.
Чтобы быть педантом, Thread.stop (Throwable)
мог вызвать исключение сразу после назначения блока try.
Однако правила с определенным назначением и смежными условиями достаточно сложны. Проверьте JLS. Попытка добавить больше правил усложнит язык и не принесет существенной пользы.