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