java.lang.ExceptionInInitializerError异常
当在静态初始化块中出现了异常的时候,JVM会抛出 java.lang.ExceptionInInitializerError异常。
如果你了解Java中的静态变量,你会知道它们是在类加载的时候进行初始化的。
如果在这个静态变量初始化的过程中出现了异常,那么就会抛出 java.lang.ExceptionInInitializerError异常。任何异常都可能会引发这种情况,比如说,java.lang.ArrayIndexOutOfBound或者java.lang.NullPointerException。
Java开发人员通常会被这个错误弄晕,他觉得自己并没有定义任何的静态初始化块,为什么还会抛出ExceptionInInitializerError异常;
事实上,Java默认会将静态变量的初始化放在一个默认的静态初始化块中,然后按它们在源文件中声明的顺序来进行初始化。比如说变量ABC声明在第一行,在第二行中使用到了,而在第三行的时候才初始化,那么第二行的代码会抛出一个NullPointerException异常,这个异常会被封装到一个ExceptionInInitializerError异常中,如果这段代码在主线程中执行了,你会看到控制台或者日志文件中出现这样的错误信息: "Exception in thread "main" java.lang.ExceptionInInitializerError"。在一个拥有大量日志文件的大型系统中,这样的错误很容易被忽略,而程序员会得到一个java.lang.NoClassDefFoundError异常。不幸的是只有当别人使用到了这个类的时候才会出现这个错误,因为ExceptionInInitializerError导致了这个类无法加载。由于类加载失败了,因此JVM会抛出NoClassDefFoundError。有的时候这会误导Java开发人员,他们会检查类路径,PATH,以及java.library.path看是不是缺少了这个类,却又发现不了任何问题,这让他们很困惑。如果你在分析NoClassDefFoundError的原因,你最好看下你的日志文件中有没有ExceptionInInitializerError,然后再考虑要不要检查classpath。本文中我们将看到一段代码,它会在静态初始化过程中引发异常从而导致 "Exception in thread "main" java.lang.ExceptionInInitializerError"。在稍后的部分,我们将会看到如何去解决这个问题。
Exception in thread "main" java.lang.ExceptionInInitializerError的原因
正如别的错误或者异常一样,当你看见这行信息,你知道这是出现ExceptionInInitializerError异常了,这个异常是由于类加载过程中静态块初始化过程失败所导致的。由于它出现在负责启动程序的主线程中,因此你最好从主类中开始分析,这里说的主类是指你在命令行参数中指定的那个,或者说是你声明了public static void main(String args[])方法的那个类。如果你仔细地看一下完整的堆栈跟踪信息,你其实什么也不用做,因为JVM已经把类名给打印出来了,这就是引发ExceptionInInitializerError的类。ExceptionInInitializerError是LinkageError的子类,这意味着这个异常会导致你的类无法加载到JVM的内存中。现在我们来看一下这个示例程序,它在执行的时候会抛出下面的异常:
|
import java.util.ArrayList;import java.util.List;/*** Java Program to understand and solve ExceptionInitializerError, which comes* <p>* When static initializer blocks throws unchecked exception during class loading* <p>* and initialization.** @author Javin Paul*/public class StaticInitializerDemo {private static final List<CreditCard> cards = new ArrayList<CreditCard>();private static CreditCard prefferdCard = cards.get(0); // 1st card is defaultpublic static boolean isVisa = "VISA".equalsIgnoreCase(prefferdCard.getNetwork());public static void main(String args[]) {makePayment(prefferdCard);}public static void makePayment(CreditCard cc) {if (isVisa) {//offer 5% discount}// deduct payment}}class CreditCard {private long card_number; //16 digit card numberprivate int cvv; // 3 digit cvv numberprivate int expiryMonth;private int expiryYear;private String bank;private String network;public CreditCard(long card_number, int cvv, int expiryMonth, int expiryYear, String bank, String network) {super();this.card_number = card_number;this.cvv = cvv;this.expiryMonth = expiryMonth;this.expiryYear = expiryYear;this.bank = bank;this.network = network;}/*** @return the card_number*/public final long getCard_number() {return card_number;}/*** @return the cvv*/public final int getCvv() {return cvv;}/*** @return the expiryMonth*/public final int getExpiryMonth() {return expiryMonth;}/*** @return the expiryYear*/public final int getExpiryYear() {return expiryYear;}/*** @return the bank*/public final String getBank() {return bank;}/*** @return the network*/public final String getNetwork() {return network;}}
输出:
Exception in
thread
"main"
java.lang.ExceptionInInitializerError
Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at StaticInitializerDemo.<clinit>(StaticInitializerDemo.java:15)
这里是Java中所有Error类的类结构。你可以看到ExceptionInInitializerError是继承自LinkageError的。还应当知道的是,像RuntimeException一样,Error也是未检查异常,编译器是不去检查有没有相应的异常处理代码的。
如何解决Exception in thread "main" java.lang.ExceptionInInitializerError
需要记住以下几点:
1. "Exception in thread "main" java.lang.ExceptionInInitializerError"意味着异常出现在主线程,并且是LinkageError的一个子类java.lang.ExceptionInInitializerError,这是JVM类加载失败时才抛出的,原因是静态初始化代码中出现了诸如IndexOutOfBoundsException或者NullPointerException这样的RuntimeException。
2. 记住JVM会将所有的静态变量的初始化按它们在源文件中的出现顺序放到一个静态初始化块中。因此,不要觉得没有看到静态初始块就认为不会出现这个异常。事实上,你得确保静态变量的正确顺序,比如说,如果 一个变量初始化的时候用到了另一个变量,你得确保这个变量在前面已经初始化过了。
3. 如果别的代码想要使用这个类,则会抛出ExceptionInInitializerError异常,而它又会导致ClassNotFoundException或者NoClassDefFoundError。为什么?因为这个类加载失败了,并没有加载到JVM的内存中。因此如果你在解决类不存在之类的异常时,先看看你的日志文件中有没有这个异常。
4. 记住静态初始化代码块会抛出RuntimeException而不是已检查异常,而后者需要有对应的catch块来进行处理。
这就是关于Exception in thread "main" java.lang.ExceptionInInitializerError的所有东西了。你已经了解到了如何去跟踪此类问题,并找出抛出这个异常的罪魁祸首。需要谨记的是这个异常的一个副作用是NoClassDefFoundError,而Java程序抛出这个异常的位置可能会离java.lang.ExceptionInInitializerError很远,这取决于你的客户端代码何时引用到这个类。因此,在查看类路径解决NoClassDefFoundError异常之前,最好先看看日志有没有出现ExceptionInInitializerError。
java.lang.ExceptionInInitializerError异常相关推荐
- java错误代码1638_Android studio报: java.lang.ExceptionInInitializerError 错误
一.问题描述 Android studio导入一个项目报一堆错误: Process: xhs.com.xhswelcomeanim, PID: 1416 Java.lang.ExceptionInIn ...
- java.lang.ExceptionInInitializerError
java.lang.ExceptionInInitializerError 问题: 1.java.lang.ExceptionInInitializerError 1.1问题描述 Exception ...
- 已解决java.lang.NoClassDefFoundError异常的正确解决方法,亲测有效!!!
已解决java.lang.NoClassDefFoundError异常的正确解决方法,亲测有效!!! 文章目录 报错问题 报错原因 解决方法 NoClassDefFoundError解决示例 福利 报 ...
- java.lang.NullPointerException异常原因及解决
java.lang.NullPointerException异常原因是因为创建了一个引用类型的变量却没有指向任何对象而又去通过这个引用类型变量加点的形式去访问非静态的方法及属性. 给出三种情况, 第一 ...
- java.lang.IllegalMonitorStateException 异常出现原因
java.lang.IllegalMonitorStateException 违法的监控状态异常.当某个线程试图等待一个自己并不拥有的对象(O)的监控器或者通知其他线程等待该对象(O)的监控器时,抛 ...
- 出现java.lang.IllegalArgumentException异常
出现java.lang.IllegalArgumentException异常 参考文章: (1)出现java.lang.IllegalArgumentException异常 (2)https://ww ...
- hibernate4 和 spring3 整合注意事项 否则java.lang.NoSuchMethodError异常
hibernate4 和 spring3 整合注意事项 否则java.lang.NoSuchMethodError异常 参考文章: (1)hibernate4 和 spring3 整合注意事项 否则j ...
- java.lang.ArrayIndexOutOfBoundsException异常分析及解决
2019独角兽企业重金招聘Python工程师标准>>> java.lang.ArrayIndexOutOfBoundsException异常分析及解决 这是一个非常常见的异常,从名字 ...
- java.lang.OutOfMemoryError异常解决方法
java.lang.OutOfmemoryError: PermGen Space 的错误,导致项目无法正常运行. 出现这个错误的原因,总结一下: PermGen Space指的是内存的永久保存区,该 ...
- Fatal error compiling: java.lang.ExceptionInInitializerError: com.sun.tools.javac.code.TypeTags
项目换用openjdk11后报错 Fatal error compiling: java.lang.ExceptionInInitializerError: com.sun.tools.javac.c ...
最新文章
- ios 百度地图指定区域_iOS开发(第三方使用)——百度地图的简单使用(定位与当前位置的显示)...
- 实际操作_MFC修改控件的Tab顺序
- boost/container/small_vector.hpp: No such file or directory on Ubuntu 14.04
- Android开发笔记(一百一十九)工具栏ToolBar
- salesforce 学习(超简介,以及传送门)
- OPNET网络仿真分析-1.1.1、网络仿真简介
- 如何做好一个流量站?
- docker+阿里云镜像容器进行环境的备份与获取
- yii2 mysql 队列_yii2.0 中的队列
- WINDOWS使用命令行关闭休眠功能
- JavaScript DOM高级程序设计 5动态修改样式和层叠样式表1(源代码)--我要坚持到底!...
- 计算机桌面快捷win10,win10系统桌面计算机快捷图标不见了的修复方案
- OpenCV实现同态滤波
- MATLAB几何均值滤波
- 快速下载github上部分文件夹或文件
- 教育学大佬是怎么找外文参考文献的?
- coap协议说明及函数使用
- IBM x3750 M4之IMM管理
- 2017第三届美亚杯全国电子数据取证大赛团队赛write up
- php使用常量和变量输出圆的面积,PHP常量和变量分别是什么?有什么区别?
热门文章
- html 京东购物车样式,购物车css样式效果
- vue4 跳转外部链接_vue项目跳转到外部链接
- 萝卜青菜各有所爱------htm 与 html
- 文件流转换为base64码 和 base64码转换为文件流
- php 服务器返回404,php--------返回404状态
- 【必看】没用的旧手机还能换钱,换换回收手机回收价格表曝光
- c语言统计大小写字母 空格 和数字个数,C++统计中英文大小写字母、数字、空格及其他字符个数的方法...
- Python游戏之运动物体寻路——A星算法与扩展
- 帐套文件(*.mdf)无法复制,拷贝出现数据错误(循环冗余检查)帐套文件(*.mdf)无法复制,拷贝出现数据错误(循环冗余检查),sql附加823错误
- WeaveSocket框架-Unity太空大战游戏-客户端-3