Всегда ли выполняется блок finally в Java?

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

Ответ

Нет, не во всех случаях. Хотя блок finally предназначен для гарантированного выполнения кода очистки после trycatch), есть ситуации, когда он не будет выполнен:

  1. Принудительное завершение JVM: System.exit(int status).
  2. Сбой виртуальной машины: Например, фатальная ошибка нативным кодом (OutOfMemoryError может, но не всегда, предотвратить выполнение finally).
  3. Принудительное завершение потока: Устаревшие методы Thread.stop() или Thread.destroy().
  4. Бесконечный цикл или deadlock внутри блока try или catch.
  5. Сбой операционной системы (например, "kill -9" на Unix).

Пример, когда finally выполнится:

try {
    System.out.println("В try");
    throw new RuntimeException("Исключение!");
} catch (RuntimeException e) {
    System.out.println("В catch: " + e.getMessage());
    // Можно сгенерировать новое исключение, finally все равно выполнится
    throw new IllegalArgumentException("Новое исключение из catch");
} finally {
    // Этот блок выполнится ВСЕГДА, даже если catch повторно выбросил исключение.
    System.out.println("В finally (гарантированно, если JVM жива)");
}

Вывод программы:

В try
В catch: Исключение!
В finally (гарантированно, если JVM жива)
Exception in thread "main" java.lang.IllegalArgumentException: Новое исключение из catch