Ресурс ресурса Try-with-resources
В конструкторе try
-with-resources Java 7 я могу объявить ресурс в инструкции try
, и он будет закрыт автоматически, когда он выходит за рамки.
Однако я не вижу никаких указаний на объем ресурса, доступный. В частности, доступен ли он в блоках catch
/finally
блока try, где он объявлен?
Я пробовал следующее в Eclipse Kepler, но это создавало смешанное впечатление:
Переменная ресурса доступна в Content Assist (Code Completion):
![Content Assist suggests resource]()
Quick Fix предлагает перейти на переменную ресурса, но это рекурсивно создает ту же проблему, которую она пытается исправить:
![Redundant suggestion in Quick Fix]()
Я хотел бы знать, что такое правильное ограничение области видимости, прежде чем поднимать ошибку в Eclipse Bug Tracker.
Ответы
Ответ 1
Этот синтаксис называется Extended try-with-resources
По JLS:
try ResourceSpecification
Block
Catchesopt
Finallyopt
Будет переведено на:
try {
try ResourceSpecification
Block
}
Catchesopt
Finallyopt
Итак, в вашем примере ваш ресурс будет ограничен внутренним блоком try, поэтому недоступен для внешнего try/catch/finally
.
EDIT:
В моем вопросе нет встроенных блоков try
Явным образом добавив блок catch/finally в ваш код, вы вводите вложенные блоки try.
Ответ 2
Правильное ограничение видимости ограничено частью декларации (...)
и фактическим блоком try
.
JLS утверждает
Объем переменной, объявленной в ResourceSpecification try-with-resources (§14.20.3) из декларации вправо над остальной частью ResourceSpecification и весь блок try, связанный с оператором try-with-resources.
Итак, из точки она объявляется в ResourceSpecification (...)
от try
вперед до окончательного закрытия }
скобки try
Block
.
TryWithResourcesStatement:
try ResourceSpecification Block Catchesopt Finallyopt
ResourceSpecification:
( Resources ;opt )
Resources:
Resource
Resource ; Resources
Resource:
VariableModifiersopt Type VariableDeclaratorId = Expression
Ответ 3
В дополнение к ответу @Nambari:
Оператор try-with-resources может иметь catch и, наконец, блокировать только как обычный пример заявления. В заявлении try-with-resources любой catch или finally выполняется после того, как объявленные ресурсы были замкнутый.
Это в значительной степени объясняет поведение, ваш ресурс выходит из области видимости в вашем явном блоке catch/finally.
Ссылка
Ответ 4
Обновление с 2017 года после выпуска Java 9
Теперь с Java 9
мы имеем больше синтаксического сахара, и у нас может быть ресурс, объявленный вне блока try-catch
, но все же обработанный должным образом. Вот почему с Java 9 улучшена поддержка Try-With-Resources, введя новый синтаксис:
InputStream stream = new MyInputStream(...)
try (stream) {
// do something with stream being sure that is going to be closed at the end
} catch(IOException e) {
// you can surely use your resource here
}
Обратите внимание, что этот синтаксис приведет к ошибке времени компиляции для Java версии 8 или младшего
Это более "естественный" способ записи, хотя в большинстве случаев нам не нужен ресурс, выходящий за рамки блока try.
Единственное ограничение состоит в том, что переменная считывателя должна быть эффективной или окончательной.
В любом случае с этим синтаксисом вы можете использовать свой ресурс также в блоке catch
и finally