Правильно ли вызывать метод close() внутри блока try?

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

Ответ

Нет, это антипаттерн. Вызов close() внутри блока try проблематичен по нескольким причинам:

  1. Нарушение логики: Ресурс должен быть доступен на протяжении всего блока try. Его преждевременное закрытие сделает последующий код в этом же блоке неработоспособным.
  2. Риск двойного закрытия: Если после этого в блоке finally также будет вызов close(), это может привести к исключению или неопределённому поведению.
  3. Исключение в close() перезапишет основное: Если в основном коде и в close() возникнут исключения, будет потеряна информация об исходной ошибке.

Правильные подходы:

A. Try-with-resources (рекомендуется с Java 7+):

try (FileInputStream fis = new FileInputStream("file.txt");
     BufferedReader br = new BufferedReader(new InputStreamReader(fis))) {
    // Работа с ресурсами
    String line = br.readLine();
    // НЕТ необходимости в ручном вызове close()
} // close() будет вызван автоматически в корректном порядке

B. Классический try-catch-finally:

BufferedReader br = null;
try {
    br = new BufferedReader(new FileReader("file.txt"));
    // Работа с ресурсом
} finally {
    if (br != null) {
        try {
            br.close(); // Закрытие В finally блоке гарантирует попытку освобождения
        } catch (IOException e) {
            // Логирование ошибки закрытия, но не подавление основной
        }
    }
}

Ключевой принцип: Блок try — для работы с ресурсом, блок finally (или автоматическое управление в try-with-resources) — для его гарантированного освобождения.