Ответ
Нет, блок finally выполняется не всегда. Хотя он предназначен для гарантированного выполнения кода очистки, существуют исключительные ситуации:
Когда finally НЕ выполнится:
- Принудительное завершение JVM: Вызов
System.exit(int)в блокеtryилиcatch. - Прерывание потока: Если поток выполнения был прерван (например,
Thread.stop()илиThread.interrupt()в определенных сценариях). - Критическая ошибка JVM: Фатальные системные ошибки, такие как
OutOfMemoryErrorили сбой нативного кода, который "убивает" процесс. - Бесконечный цикл: Если код в блоке
tryилиcatchзацикливается и никогда не завершается.
Пример с System.exit():
try {
System.out.println("Inside try block");
System.exit(0); // Немедленное завершение JVM
} finally {
// Этот код никогда не выполнится
System.out.println("Inside finally block");
}
Практическое применение: В нормальных условиях finally выполняется вне зависимости от того, было выброшено исключение или нет. Это делает его идеальным местом для освобождения ресурсов: закрытия файловых потоков (FileInputStream), сетевых соединений или объектов Scanner.
try (Scanner scanner = new Scanner(new File("test.txt"))) {
// Автоматическое управление ресурсами (try-with-resources) предпочтительнее
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// Для ресурсов, не поддерживающих AutoCloseable, используйте finally:
Scanner oldScanner = null;
try {
oldScanner = new Scanner(new File("old.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (oldScanner != null) {
oldScanner.close(); // Гарантированное закрытие
}
}