Может ли конечная переменная быть переназначена в catch, даже если присваивание является последней операцией в try?
Я вполне уверен, что здесь
final int i;
try { i = calculateIndex(); }
catch (Exception e) { i = 1; }
i
возможно, уже не был назначен, если управление достигает блока захвата. Тем не менее, компилятор Java не согласен и утверждаетthe final local variable i may already have been assigned
.
Есть ли еще какая-то тонкость, которую я здесь упускаю, или это просто слабость модели, используемой Спецификацией языка Java для выявления потенциальных переназначений? Мое главное беспокойство такие вещи, какThread.stop()
, что может привести к тому, что исключение будет выброшено «из воздуха», но я до сих пор не понимаю, как оно может быть выброшено после назначения, что, по-видимому, является самым последним действием в блоке try.
Приведенная выше идиома, если позволят, упростит многие из моих методов. Обратите внимание, что этот вариант использования имеет первоклассную поддержку в языках, таких как Scala, которые последовательно используютМожет быть монада:
final int i = calculateIndex().getOrElse(1);
Я думаю, что этот вариант использования является довольно хорошей мотивацией для того, чтобы этот особый случай, когдаi
являетсяопределенно не назначен в пределах блока захвата.
После некоторых размышлений я еще более уверен, что это всего лишь слабость модели JLS: если я объявлю аксиому "в представленном примере,i
определенно не назначен, когда управление достигает блока catch ", оно не будет конфликтовать с любой другой аксиомой или теоремой. Компилятор не позволит читатьi
до того, как он назначен в блоке catch, поэтому фактi
был назначен или не может быть соблюден.