Подтвердить что ты не робот

Нечетная Java StackOverflowError?

Почему этот код полностью разрушает вывод?

public class Main {
    public static void main(String[] args) {
        System.out.println();

        rec();
    }

    private static int rec() {
        try {
            return rec();
        } catch(StackOverflowError e) {
            System.out.println("Boo.");
            return 0;
        }
    }
}

Образец вывода: Boo.Boo.Boo.Boo.Boo.Boo.Boo.Boo.Boo.

4b9b3361

Ответ 1

Проблема аналогична проблеме в этом вопросе: Обработка ошибок в блоке finally

В принципе, вызов println вашего обработчика для StackOverflowException запускает следующий StackOverflowException. Это выполняется во входящем вызове rec(). Это продолжается (разматывая вызовы rec(), когда мы идем), пока обработчик исключений не получит достаточно места для завершения вызова println. Промежуточные вызовы, вероятно, добавляют символы в выходной буфер, а затем поднимают SOE.

Точное объяснение потребует криминалистического анализа кода PrintStream и стека потока... вплоть до точки, в которой он вызывает собственный код.


Если вы хотите мета-объяснение, это то, что ваш код пытается восстановить из Error... который, по словам javadocs, является тем, что вы не должны пытаться делать. Как правило, после Error, JVM будет неопределенным и, возможно, сломанным состоянием. В этом случае неопределенность проявляется как данные, которые могут быть или не были записаны в буфер. Поведение (возможно) детерминировано, но определенно трудно анализировать и невозможно предсказать без надлежащего анализа.