是否可以捕获 ExceptionInInitializerError?

rgh*_*rgh 5 java

任何 Throwable 都可以被捕获

class CatchThrowable {      
  public static void main(String[] args){
    try{
      throw new Throwable();
    } catch (Throwable t){
      System.out.println("throwable caught!");
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

输出:

throwable caught!
Run Code Online (Sandbox Code Playgroud)

因此,如果我在初始化块期间做了一些不好的事情,我希望能够捕获一个 ExceptionInInitializerError。但是,以下方法不起作用:

class InitError {
  static int[] x = new int[4];
  static {                                                           //static init block
    try{
      x[4] = 5;                                                      //bad array index!
    } catch (ExceptionInInitializerError e) {
      System.out.println("ExceptionInInitializerError caught!");
    } 
  }           
  public static void main(String[] args){}
}
Run Code Online (Sandbox Code Playgroud)

输出:

java.lang.ExceptionInInitializerError
Caused by: java.lang.ArrayIndexOutOfBoundsException: 4
    at InitError.<clinit>(InitError.java:13)
Exception in thread "main" 
Run Code Online (Sandbox Code Playgroud)

如果我更改代码以额外捕获 ArrayIndexOutOfBoundsException

class InitError {
  static int[] x = new int[4];
  static {                                                           //static init block
    try{
      x[4] = 5;                                                      //bad array index!
    } catch (ExceptionInInitializerError e) {
      System.out.println("ExceptionInInitializerError caught!");
    } catch (ArrayIndexOutOfBoundsException e){
      System.out.println("ArrayIndexOutOfBoundsException caught!");
    }
  }           
  public static void main(String[] args){}
}
Run Code Online (Sandbox Code Playgroud)

它是 ArrayIndexOutOfBoundsException 被捕获:

ArrayIndexOutOfBoundsException caught!
Run Code Online (Sandbox Code Playgroud)

谁能告诉我这是为什么?

das*_*ght 5

顾名思义,ExceptionInInitializerError是错误,而不是例外。与异常不同,错误并不意味着被捕获。它们表示致命的不可恢复状态,旨在停止您的程序。

ExceptionInInitializerError表示static变量的初始值设定项抛出了一个尚未捕获的异常 - 在您的情况下,它是ArrayIndexOutOfBoundsException,但任何异常都会导致此错误。由于静态初始化发生在正在运行的程序的上下文之外,因此没有地方可以传递异常。这就是 Java 产生错误而不是传递异常的原因。