Ответ
Try-with-resources превосходит ручное управление (try-catch-finally) по надёжности, читаемости и безопасности.
Сравнение подходов:
1. Ручное управление (проблемный шаблон):
// Проблемы: многословно, легко ошибиться, исключение при close() может перезаписать основное
FileInputStream fis = null;
try {
fis = new FileInputStream("data.bin");
// ... работа с файлом
int data = fis.read();
} catch (IOException e) {
// Обработка ошибки чтения
} finally {
if (fis != null) {
try {
fis.close(); // Исключение здесь скроет исключение из блока try!
} catch (IOException closeException) {
// Игнорируется или логируется, теряя контекст
}
}
}
2. Try-with-resources (рекомендуемый способ):
try (FileInputStream fis = new FileInputStream("data.bin")) {
int data = fis.read(); // Основная логика
// ...
} catch (IOException e) {
// Обработка ИСКЛЮЧИТЕЛЬНО из блока try или из close()
// Исключения от close() не теряются, а добавляются как подавленные
for (Throwable suppressed : e.getSuppressed()) {
System.err.println("Suppressed error on close: " + suppressed);
}
}
Ключевые преимущества try-with-resources:
- Гарантированное закрытие: Компилятор гарантирует вызов
close(). - Корректная обработка исключений: Исключение из блока
tryимеет приоритет. Исключения отclose()не теряются, а присоединяются как подавленные. - Устранение шаблонного кода: Нет нужды в громоздких блоках
finally. - Защита от ошибок: Невозможно забыть закрыть ресурс.
- Поддержка нескольких ресурсов: Удобное объявление нескольких ресурсов.
Практическое правило: Всегда используйте try-with-resources для любых ресурсов, реализующих AutoCloseable (InputStream, OutputStream, Connection, Statement, Socket и т.д.).