Если вы инициализируете два Throwable
s как взаимные причины друг друга, вы получите StackOverflowError
, если попытаетесь распечатать трассировку стека одного из них.
Следующий класс демонстрирует этоПоведение:
public class StackTraceStackOverflow {
public static void main(String[] args) {
Error e = new Error();
Error f = new Error(e);
e.initCause(f);
e.printStackTrace();
}
}
Нам нужно два Throwable
в этом примере, потому что невозможно установить Throwable
в качестве его собственной причины.Если вы попытаетесь это сделать, вы получите IllegalArgumentException
.
В качестве альтернативы, вы также можете получить ошибку переполнения стека, если у вас есть смехотворно длинная цепочка исключений причины.По крайней мере, на моей машине (Kubuntu Natty, x64, OpenJDK 1.6) я обнаружил, что для генерирования StackOverflowError
достаточно цепочки из 8000 исключительных ситуаций, как демонстрирует следующий класс:необходимо настроить число 8000 в других системах.
Обратите внимание, что я использовал конструктор с двумя аргументами Error
во втором примере.Если я использовал конструктор, который принимает один параметр Throwable
, сообщение об исключении заполняется с использованием причины исключения.Это сообщение становится все длиннее и длиннее по мере роста цепочки исключений, и в результате вы с большей вероятностью получите OutOfMemoryError
, чем StackOverflowError
.