Я заметил, что это не будет компилироваться:
PrintWriter printWriter = new PrintWriter("test.txt");
printWriter.append('a');
printWriter.close();
printWriter = null;
try(printWriter = new PrintWriter("test.txt")) {
}
С: Error:(17, 24) java: <identifier> expected
На данный момент работает только новая переменная:
try(PrintWriter printWriter2 = new PrintWriter("test.txt")) {
}
Моя интуиция такова, что требуется только новый объект, но, видимо, нужна новая ссылка. Ясно, что это результат проверки типов во время компиляции, но почему старая ссылка не работает?
2 ответа
Ответ прост, потому что он будет закрыт после завершения попытки с ресурсами. В частности,
JLS 14.20.3. try-with-resources говорит частично (выделено жирным шрифтом),
ResourceSpecification объявляет одну или несколько локальных переменных с выражениями инициализатора, которые действуют как ресурсы для оператора try.
Ресурс, объявленный в ResourceSpecification, неявно объявляется окончательным (§4.12.4), если он не объявлен явно окончательным.
Тип переменной, объявленной в ResourceSpecification, должен быть подтипом AutoCloseable, иначе произойдет ошибка времени компиляции.
Самый неудовлетворительный ответ, потому что грамматика, определенная в спецификации, требует объявления переменной. Глядя на спецификацию 14.20.3 грамматика
TryWithResourcesStatement:
try ResourceSpecification Block Catchesopt Finallyopt
ResourceSpecification:
( Resources ;opt )
Resources:
Resource
Resource ; Resources
Resource:
VariableModifiers[opt] Type VariableDeclaratorId = Expression
Мы видим, что для TryWithResourcesStatement
требуется ResourceSpecification
, который представляет собой один или несколько Resource
, заключенных в круглые скобки и разделенных точкой с запятой. Для каждого ресурса требуется тип и имя (Type
и VariableDeclaratorId
).
Поэтому компилятор требует этого, потому что этого требует спецификация. Вам нужно будет углубиться в процесс создания этой функции, чтобы выяснить, почему она была сочтена необходимой.
Похожие вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.