Ответ
Начиная с Java 7, для этого используется конструкция try-with-resources. Она автоматически закрывает любые ресурсы, реализующие интерфейсы AutoCloseable или Closeable.
Синтаксис и пример:
try (FileInputStream fis = new FileInputStream("file.txt");
BufferedInputStream bis = new BufferedInputStream(fis)) {
// Работа с ресурсами
int data = bis.read();
} // Здесь fis и bis будут автоматически закрыты, даже если выброшено исключение
Как это работает и почему это лучше:
- Автоматическое закрытие: Компилятор генерирует блок
finally, который вызываетclose()для каждого объявленного ресурса в обратном порядке. - Подавление исключений: Если в блоке
tryи вclose()возникли исключения, исключение изtryбудет основным, а изclose()— подавленным (доступно черезThrowable.getSuppressed()). - Сравнение с ручным управлением (до Java 7):
// Старый, многословный и подверженный ошибкам способ FileInputStream fis = null; try { fis = new FileInputStream("file.txt"); // работа... } finally { if (fis != null) { try { fis.close(); // Может тоже выбросить исключение } catch (IOException e) { // Логирование, часто игнорируется } } }
Практическое правило: Всегда предпочитайте try-with-resources ручному закрытию в finally. Это делает код чище, безопаснее и предотвращает утечки ресурсов.