Какое условие должен выполнять класс, чтобы его можно было использовать в конструкции try-with-resources в Java?

«Какое условие должен выполнять класс, чтобы его можно было использовать в конструкции try-with-resources в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Класс должен реализовывать интерфейс java.lang.AutoCloseable (введен в Java 7) или его подынтерфейс java.io.Closeable.

Условие: Интерфейс AutoCloseable объявляет всего один метод:

void close() throws Exception;

Как это работает: При выходе из блока try (нормальном или из-за исключения) JVM автоматически вызывает метод close() для каждого объявленного ресурса в обратном порядке их инициализации.

Пример корректного использования:

// FileInputStream реализует AutoCloseable (через Closeable)
try (FileInputStream fis = new FileInputStream("file.txt");
     Scanner scanner = new Scanner(fis)) { // Scanner тоже реализует Closeable
    while (scanner.hasNextLine()) {
        System.out.println(scanner.nextLine());
    }
} // Здесь автоматически вызываются scanner.close() и fis.close()
// Исключения в close() подавляются, но добавляются в suppressed exceptions

Пример некорректного использования:

try (String notACloseableResource = "Hello") { // ОШИБКА КОМПИЛЯЦИИ
    // String не реализует AutoCloseable
}

Ключевые преимущества try-with-resources:

  1. Автоматическое управление ресурсами: Гарантированное закрытие, даже при возникновении исключения.
  2. Улучшенная читаемость: Код становится чище по сравнению с ручным finally-блоком.
  3. Подавленные исключения (suppressed exceptions): Если в try и в close() возникли исключения, исключение из try будет основным, а из close() — подавленным (доступно через getSuppressed()).