Выполнится ли блок `finally`, если в `try` или `catch` вызвать `System.exit()`?

Ответ

Нет, блок finally не выполнится.

Причина: Вызов System.exit(int status) немедленно завершает работу виртуальной машины Java (JVM). Этот процесс останавливает все потоки, включая тот, в котором должен был выполняться блок finally.

Пример, демонстрирующий это поведение:

public class FinallyAndSystemExit {
    public static void main(String[] args) {
        try {
            System.out.println("Внутри try-блока");
            System.exit(0); // JVM завершается здесь
        } catch (Exception e) {
            System.out.println("Внутри catch-блока");
        } finally {
            // Этот код НИКОГДА не выполнится
            System.out.println("Внутри finally-блока");
        }
        System.out.println("После try-catch-finally");
    }
}

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

Внутри try-блока

Важное исключение: Если System.exit() вызывается внутри блока catch или try, но до этого JVM уже запустила shutdown hook (хуки завершения), то эти shutdown hooks будут выполнены. Однако блок finally текущего try-catch выполнен не будет.

Ответ 18+ 🔞

Да ты посмотри, какая интересная хуйня вырисовывается! Ну, сидишь ты такой, пишешь свой код, и думаешь: "Ага, finally — это же святое, он всегда выполнится, как бы ни вывернулась программа". Ан хуй там плавал!

Вот смотри, есть у нас такая команда — System.exit(). Это, блядь, не какая-то там исклюушина, это приказ прямой, как выстрел в затылок. Виртуальная машина Java её получает и сразу, без разговоров, накрывается медным тазом. Всё. Точка. Никаких "ой, подожди, я там ещё блок finally не отработал". Ей уже похуй, она тухнет на месте.

Вот тебе живой пример, смотри, как это выглядит в коде:

public class FinallyAndSystemExit {
    public static void main(String[] args) {
        try {
            System.out.println("Внутри try-блока");
            System.exit(0); // JVM завершается здесь
        } catch (Exception e) {
            System.out.println("Внутри catch-блока");
        } finally {
            // Этот код НИКОГДА не выполнится
            System.out.println("Внутри finally-блока");
        }
        System.out.println("После try-catch-finally");
    }
}

Запускаешь эту поделку и что видишь? Только строчку "Внутри try-блока". И всё! Тишина. Пиздец. Блок finally даже не пискнул, как та Муму, когда её в озеро кинули. И всё, что после — тоже в пизду.

Есть, конечно, одна хитрая жопа, называемая shutdown hook. Это такие специальные потоки, которые JVM, перед тем как сдохнуть, может успеть позвать на последний танец. Но это, блядь, отдельная история, и к твоему родному finally в текущем try-catch они отношения не имеют. Твой finally так и останется невинным девственником, не выполненным.

Так что запомни, чувак: System.exit() — это волшебный пендель, который выбивает дверь и выносит всю JVM нахуй, не глядя на твои церемонии с finally. Ёпта, вот такие пироги с котятами.