Гарантирует ли блок finally в Java автоматическое закрытие ресурсов?

«Гарантирует ли блок finally в Java автоматическое закрытие ресурсов?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нет. Блок finally гарантирует свое выполнение (за исключением крайних случаев), но не закрывает ресурсы автоматически. Ответственность за явный вызов метода закрытия (например, .close()) лежит на разработчике.

Способ 1: Явное закрытие в finally (до Java 7)

FileInputStream fis = null;
try {
    fis = new FileInputStream("file.txt");
    // работа с ресурсом
} catch (IOException e) {
    // обработка ошибки
} finally {
    if (fis != null) {
        try {
            fis.close(); // Закрытие вручную
        } catch (IOException e) {
            // Логирование ошибки закрытия
        }
    }
}

Способ 2: Try-with-resources (Java 7+, рекомендуется) Автоматически закрывает ресурсы, реализующие интерфейс AutoCloseable.

try (FileInputStream fis = new FileInputStream("file.txt");
     BufferedReader br = new BufferedReader(new InputStreamReader(fis))) {
    // работа с ресурсами
} // fis и br закроются здесь автоматически, даже при исключении

Важное замечание: Если исключение возникнет и в try-блоке, и при закрытии в finally (или в неявном close() try-with-resources), исключение из finally/close() будет добавлено как suppressed exception к основному.