Class.forName + ExceptionInInitializerError + 静态初始化 + 奇怪的数组 init

问题描述

我最近“继承”了一个项目并尝试获取本地运行的服务实例。我遇到 - 并修复了 - 一些类似于...的代码问题

class A {
   // ...
   public void doSomething() {
      // ...
      Class foo = Class.forName("fully.qualified.package.B"); 
      // ...  
   }
   // ...
}

class B {
    static String[] bar = (String[])Arrays.asList("Something").toArray();
    //...
}

当 Class A.doSomething() 运行时,会抛出一个 ExceptionInInitializerError。此错误与初始化 B 类有关(静态初始化,没有实例化!!)。

仅供参考>可以通过两种方式解决此问题...

  • A 类,使用 Class.forName("fully.qualified.package.B",false,this.getClass().getRuntime()); - 其中第二个参数 false 不初始化类。
  • B 类,使用普通数组 init static String[] bar = { "Something" };

我感兴趣的是...

为什么通过 (String[]) Arrays.asList(...).toArray() 稍微过度设计的初始化会导致这样的错误


解决方案/编辑:它与静态初始化无关,数组 init 显然是错误的,见下文...

解决方法

(String[])Arrays.asList("Something").toArray(); 将在运行时失败:它不会返回 String[],而是返回 Object[]Object[]String[] 是可具体化的类型,因此它是经过检查的强制转换,并且因为 Object[] 不是 String[],所以它失败了。

使用Arrays.asList("Something").toArray(new String[0]);或者只是new String[]{"Something"}