Что делает конструкция try-with-resources?
- Что такое AutoCloseable?
- Что такое подавленные исключения (suppressed)?
- Чем try-with-resources лучше finally?
- Что требуется от ресурса, чтобы работать в try-with-resources?
try-with-resources гарантированно закрывает ресурсы при любом выходе из блока — без ручного finally.
- Ресурс должен реализовывать AutoCloseable; закрываются в обратном порядке объявления
- Ошибка при закрытии не затирает основное исключение — сохраняется как suppressed
А ещё Перехват исключений — отдельно: catch пишут как обычно
Подробно
Ресурсы — файлы, соединения с базой, сокеты — нужно закрывать, иначе они утекают. Раньше это делали в finally с проверкой на null и вложенным try, и код получался громоздким и с ошибками.
Конструкция try (Resource r = ...) { ... } закрывает объявленные ресурсы автоматически при любом выходе: обычном, через return или исключение. Требование одно — ресурс реализует AutoCloseable (или Closeable). Если ресурсов несколько, они закрываются в обратном порядке объявления.
Решена и вторая проблема ручного подхода. Если в блоке возникло исключение, а потом упало ещё и close(), в старом коде исключение из finally затирало исходное — терялась настоящая причина. В try-with-resources основным остаётся исключение из блока, а ошибка закрытия прикрепляется к нему как подавленное (getSuppressed()).
С Java 9 можно указывать уже объявленную effectively final переменную: try (conn) { ... }.
Пример
try (var conn = dataSource.getConnection();
var stmt = conn.prepareStatement("SELECT name FROM users WHERE id = ?")) {
stmt.setLong(1, id);
try (var rs = stmt.executeQuery()) {
return rs.next() ? rs.getString(1) : null;
}
} // rs, stmt и conn закрыты, даже если было исключениеЧто хотят услышать
- Автоматическое закрытие при любом выходе из блока.
- Требование AutoCloseable и порядок закрытия.
- Подавленные исключения вместо затирания основного.
Частые ошибки
- Закрывать ресурс вручную внутри блока и получать двойное закрытие.
- Считать, что конструкция сама обрабатывает исключения.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Перехватывает и логирует все исключения, брошенные внутри блока
- ✓Закрывает объявленные ресурсы при любом выходе из блока
- ✗Повторяет операцию при ошибке
- ✗Выполняет блок в отдельном потоке
Что спросят дальше
- Что произойдёт, если исключения бросят и тело блока, и закрытие?
- В каком порядке закрываются несколько ресурсов?
- Чем Closeable отличается от AutoCloseable?
Разбор темы
- Управление ресурсами: try-with-resources
Беды ручного finally, автозакрытие AutoCloseable, suppressed-исключения и разница Closeable/AutoCloseable.
Связанные вопросы
- Код открывает соединение, затем в том же try создаёт из него statement, и оба объявлены в скобках try-with-resources. В каком порядке они закроются? Middle
- В try-with-resources исключение бросают и тело блока, и метод close(). Какое исключение получит вызывающий код? Middle
- Чем интерфейс AutoCloseable отличается от Closeable? Middle
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.