Почему вы не можете вызвать initCause с ExceptionInInitializerError?

1

Почему вызов 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?

Теги:
exception
error-handling

1 ответ

2

Поскольку я изучал этот вопрос, я просматривал исходный код для 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
}

Не совсем понимаю, почему на самом деле, но кажется, что это смесь устаревшего кода, который нельзя переоснастить, и "просто потому, что".

Ещё вопросы

Сообщество Overcoder
Наверх
Меню