Что такое конструкция try-with-resources и зачем она нужна в Java
Что проверяют
Понимаете ли вы, что она решает не только вопрос «не забыть закрыть», но и проблему потерянного исключения.
Как отвечать
Это конструкция, объявляющая ресурсы в скобках после try. Ресурс должен реализовывать AutoCloseable, и его close() вызывается автоматически при выходе из блока, в том числе при исключении и при досрочном возврате.
try (var in = new FileInputStream(src);
var out = new FileOutputStream(dst)) {
in.transferTo(out);
}Закрытие идёт в порядке, обратном объявлению, что важно для вложенных ресурсов вроде потока поверх соединения.
Зачем она нужна, по пунктам:
- ресурс закрывается всегда, и не нужен блок
finallyс проверкой наnullи вложеннымtryвокруг самогоclose(); - вложенность исчезает: раньше два ресурса означали два уровня
try-finally; - исключение больше не теряется, и это главное. В старом коде, если тело бросило одно исключение, а
close()вfinallyбросил другое, наружу уходило второе, и настоящая причина сбоя пропадала. Здесь наоборот: основным остаётся исключение из тела, а исключение изclose()подавляется и доступно черезgetSuppressed().
Стоит знать про версии: конструкция появилась в Java 7, а с Java 9 в скобках можно указать уже объявленную переменную, если она фактически финальная, поэтому не приходится плодить локальные копии.
Что не покрывается: если ресурс не реализует AutoCloseable, конструкция неприменима, и остаётся finally. И close() у некоторых реализаций может бросать исключение при сбросе буфера, поэтому у файла, в который писали важные данные, иногда закрывают явно, чтобы обработать ошибку записи.
Где спотыкаются
Не знают про подавленные исключения и теряют исходную ошибку.
Открывают ресурс до try, а в скобках только присваивают.
Думают, что закрытие идёт в порядке объявления.
Пишут close() вручную в теле и получают двойное закрытие.