• JDK中对ExceptionInInitializerError的描述是:
    在静态初始化程序中发生了意料之外的异常的信号。在一个静态初始化程序求值的时候,或者静态字段初始化的时候发生了异常,就会抛出一个ExceptionInInitializerError异常。

  • JDK中对NoClassDefFoundError的描述是:
    JVM(Java虚拟机)或者类装载器(ClassLoader)实例试图去装载一个class定义的时候发现class的定义找不到了。被查找的class定义在当前执行的class被编译的时候是存在的,但是运行的时候找不到了。

       但是笔者发现,在调用一个静态字段初始化有问题的class的时候,第一次报错是ExceptionInInitializerError,第二次再调用就报错NoClassDefFoundError了。说明Java虚拟机或者类加载器在发现class不可用的时候,就不去装载它了,直接认为找不到它。可以通过如下代码查看到这种情况。

JDK1.8运行如下代码:

package com.example.demo;

/**
 * @description:
 * @author: pilaf
 * @create: 2019-05-20 13:32
 */
public class MyTest {

    static class MyConstants{
    	//故意制造一个运行时异常
        static final Integer CODE = (1 / 0);
    }

    public static void main(String[] args) {
        try {
            System.out.println("第一次调用");
            System.out.println(MyConstants.CODE);
        } catch (Throwable e) {//抛出的是Error,用Exception catch不住,所以用Throwable
            System.out.println("第一次调用报错\n"+e);
            System.out.println("第一次调用报错原因\n"+e.getCause());
        }

        try {
            System.out.println("第二次调用");
            System.out.println(MyConstants.CODE);
        } catch (Throwable e) {
            System.out.println("第二次调用报错\n"+e);
            System.out.println("第二次调用报错原因\n"+e.getCause());
        }

        try {
            System.out.println("第三次调用");
            System.out.println(MyConstants.CODE);
        } catch (Throwable e) {
            System.out.println("第三次调用报错\n"+e);
            System.out.println("第三次调用报错原因\n"+e.getCause());
        }
    }
}

输出的内容如下:

第一次调用
第一次调用报错
java.lang.ExceptionInInitializerError
第一次调用报错原因
java.lang.ArithmeticException: / by zero

第二次调用
第二次调用报错
java.lang.NoClassDefFoundError: Could not initialize class com.example.demo.MyTest$MyConstants
第二次调用报错原因
null

第三次调用
第三次调用报错
java.lang.NoClassDefFoundError: Could not initialize class com.example.demo.MyTest$MyConstants
第三次调用报错原因
null
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐