Начиная с Java 9 мы можем эффективно использовать конечные переменные в try-with-resources.
В приведенном ниже примере представлена ситуация, когда инициализация одного из ресурсов вызывает исключение.
public static void main(String[] args) {
Resource1 r1 = new Resource1();
Resource2 r2 = new Resource2(); // exception will be thrown
try (r1; r2) {
System.out.println("TryWithResources.main() try");
} catch (Exception e) {
System.out.println("TryWithResources.main() catch");
}
}
static class Resource1 implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("TryWithResources.Resource1.close()");
}
}
static class Resource2 implements AutoCloseable {
public Resource2() {
throw new RuntimeException();
}
@Override
public void close() throws Exception {
System.out.println("TryWithResources.Resource2.close()");
}
}
Когда я запускаю этот пример, единственный вывод, который я получаю, — это RuntimeException, что означает, что Resource1 не был закрыт. Этого и следовало ожидать, так как он не был инициализирован в try-with-resources.
Но это ожидаемый результат, или я что-то упускаю?
Потому что, если это действительно так, как это должно работать, то мне кажется, что этот новый синтаксис на самом деле устраняет большую часть безопасности, которая изначально была привнесена оператором try-with-resources.
Может кто-нибудь подтвердить, так ли это на самом деле? И, если да, то зачем нам использовать этот синтаксис с несколькими ресурсами и идти на такой риск?