Неинициализированная переменная Java с наконец любопытством

Можно записать специальное средство выделения "кучи" для определенных размеров объектов, которое очень производительно. Однако общий средство выделения "кучи" не особенно производительно.

Также я соглашаюсь с TorbjГ¶rn Gyllebring об ожидаемом времени жизни объектов. Положительная сторона!

6
задан Joshua Warner 8 August 2009 в 05:57
поделиться

6 ответов

Может показаться нелогичным, что исключение могло произойти в строке a = 1, но могла возникнуть ошибка JVM. Таким образом, оставив переменную неинициализированной. Итак, ошибка компилятора имеет смысл. Это та неясная ошибка времени выполнения, о которой вы упомянули. Однако я бы сказал, что OutOfMemoryError далеко не непонятен и разработчики должны хотя бы подумать о нем. Кроме того, помните, что состояние, которое устанавливает OutOfMemoryError, может произойти в другом потоке, и единственное действие, которое выталкивает объем памяти кучи, превышающий предел, - это присвоение переменной a.

В любом случае, поскольку вы смотрите на компилятор design, я также предполагаю, что вы уже знаете, насколько глупо возвращать значения в блоке finally.

10
ответ дан 8 December 2019 в 04:30
поделиться

Спецификация языка Java требует, чтобы переменная была назначена перед ее использованием. JLS определяет особые правила для правил, известных как правила «Определенного назначения». Все компиляторы Java должны их придерживаться.

JLS 16.2.15 :

V определенно назначается перед блоком finally, если и только если V определенно назначается перед оператором try.

Другими словами, при рассмотрении оператор finally, операторы блока try и catch внутри оператора try-catch-finally не рассматриваются.

Излишне говорить, что эта спецификация здесь очень консервативна, но они предпочли бы спецификация должна быть простой, но немного ограниченной (полагаю, что правила уже сложны), чем быть снисходительной, но трудной для понимания и рассуждений.

Компиляторы должны следовать этим правилам определенного присвоения, поэтому все компиляторы выдают одни и те же ошибки. Компиляторам не разрешается выполнять какой-либо дополнительный анализ, кроме указанного в JLS , для подавления любых ошибок.

7
ответ дан 8 December 2019 в 04:30
поделиться

Я считаю, что это просто из-за семантики отношения «попробуй-поймай-наконец». Из Спецификации языка Java :

Если выполнение блока try завершается нормально, затем наконец блок выполняется ...

Если выполнение блока try завершается внезапно из-за броска значения V ...

Если выполнение блока try завершается внезапно для любого другого причина R, то блок finally казнен ...

Последний случай кажется здесь наиболее актуальным. Кажется, что блок finally должен иметь возможность правильно выполняться, если блок try завершается внезапно по ЛЮБОЙ причине. Очевидно, что если блок try закончится до назначения, блок finally будет недействителен. Хотя, как вы сказали, это маловероятно.

3
ответ дан 8 December 2019 в 04:30
поделиться

Весьма вероятно, что javac требуется, чтобы сделать общее предположение, что исключение может произойти в любой точке блока try, даже во время присваивания, и что, следовательно, finally может вернуть неинициализированную переменную. Теоретически он мог бы провести подробный анализ и обнаружить, что на всех путях, проходящих через блок попытки, «a» всегда будет успешно инициализироваться, но это трудоемкая работа практически без выгоды.

Теперь, если кто-то просто может указать на соответствующий раздел в Спецификации языка Java ...

2
ответ дан 8 December 2019 в 04:30
поделиться

Я предполагаю, что компилятор Java предполагает худший случай - нет гарантии, что что-либо в блоке try даже выполняется по какой-либо причине. Итак, его жалоба действительна. Переменная могла не быть инициализирована.

1
ответ дан 8 December 2019 в 04:30
поделиться

Компилятор здесь просто консервативен.

0
ответ дан 8 December 2019 в 04:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: