类静态字段初始化错误导致的ExceptionInInitializerError和NoClassDefFoundError

  • 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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值