Почему вызов initCause
с ExceptionInInitializerError
приводит к ExceptionInInitializerError
IllegalStateException
?.
public class Test {
public static final void main(String[] ignored) {
try {
ExceptionInInitializerError err = new ExceptionInInitializerError("1. Fail!");
err.initCause(new NullPointerException("null!"));
throw err;
} catch(Exception x) {
x.printStackTrace();
}
System.out.println();
try {
IllegalStateException isx = new IllegalStateException("2. Fail!");
isx.initCause(new NullPointerException("null!"));
throw isx;
} catch(Exception x) {
x.printStackTrace();
}
System.out.println();
try {
throw new IllegalStateException("3. Fail!", new NullPointerException("null!"));
} catch(Exception x) {
x.printStackTrace();
}
}
}
Вывод:
java.lang.IllegalStateException: Can't overwrite cause with java.lang.NullPointerException: null!
at java.lang.Throwable.initCause(Throwable.java:456)
at Test.main(Test.java:5)
Caused by: java.lang.ExceptionInInitializerError: 1. Fail!
at Test.main(Test.java:4)
java.lang.IllegalStateException: 2. Fail!
at Test.main(Test.java:14)
Caused by: java.lang.NullPointerException: null!
at Test.main(Test.java:15)
java.lang.IllegalStateException: 3. Fail!
at Test.main(Test.java:24)
Caused by: java.lang.NullPointerException: null!
... 1 more
Я ничего не вижу в документации, для конструктора или для самого класса, который либо говорит (а), что это недопустимо, либо (б) почему это не разрешено. Я вижу, что "There is no saved throwable object."
в JavaDoc, но для меня это означает, что можно установить.
Это "просто потому, что", или есть причина, почему вы не можете установить причину ExceptionInInitializerError
?
Поскольку я изучал этот вопрос, я просматривал исходный код для ExceptionInInitializerError
.
Во-первых, это в классе JavaDoc:
Начиная с версии 1.4, это исключение было дооснащено, чтобы соответствовать механизму исключения исключений общего назначения. "Сохраненный перемещаемый объект", который может быть предоставлен во время построения и доступ через метод getException(), теперь известен как причина и может быть доступен через метод Throwable.getCause(), а также вышеупомянутый "унаследованный" метод. "
Нет ничего о том, что "не использовать initCause
", но это, по-видимому, самое близкое, что вы собираетесь получить.
Конструкторы явно делают это невозможным, а внутренние комментарии намного яснее, чем что-либо в JavaDoc (в котором говорится только "Нет сохраненного объекта, который можно добавить"):
/**
<P>... There is no saved throwable object.</P>
**/
public ExceptionInInitializerError() {
initCause(null); // Disallow subsequent initCause
}
public ExceptionInInitializerError(Throwable thrown) {
initCause(null); // Disallow subsequent initCause
this.exception = thrown;
}
public ExceptionInInitializerError(String s) {
super(s);
initCause(null); // Disallow subsequent initCause
}
Не совсем понимаю, почему на самом деле, но кажется, что это смесь устаревшего кода, который нельзя переоснастить, и "просто потому, что".