java.lang.ExceptionInInitializerError异常分析
今天在项目开发时遇到一个问题,整个项目是使用Spring等框架搭建起来的在运行项目时不报任何的异常信息,就是找不到某个类信息,各方查找该类确实是存在的,最后通过断点跟踪时在异常栈内发现java.lang.ExceptionInInitializerError这个异常信息,但这个异常信息没有在控制台或者日志系统中抛出来,查明原因之后就对症下药最终解决了该问题。查找该问题也着实费了一翻功夫,正好趁此机会把该问题引发的原因及针对这类问题应该如何来避免记录一下。由于该项目中的代码比较复杂,这里举一个简单的例子来说明一下该异常产生的原因。
java.lang.ExceptionInInitializerError
该异常在Java中的继承关系如下:
下面是jdk对该异常的描述
public class ExceptionInInitializerError
extends LinkageError
静态初始化程序中发生意外异常的信号。抛出 ExceptionInInitializerError 表明在计算静态初始值或静态变量的初始值期间发生异常。
从版本 1.4 开始,这个异常已经更新过,符合通用异常链机制。“保存的 throwable 对象”可能是在构造的时候提供的,并且可以通过 getException() 方法来访问,这类对象目前被认为是导致异常的原因,可以通过 Throwable.getCause() 方法以及前面提到的“遗留方法”访问它。
要理解这个异常还得从Java类中的静态变量初始化过程说起,在Java类中静态变量的初始化顺序和静态变量的声明顺序是一致的。为了验证该说法,我们写一个简单的小程序,代码如下:
-
/**
-
*
-
*/
-
package com.mhy.oo.statics;
-
-
import java.util.ArrayList;
-
import java.util.List;
-
-
/**
-
* @author mhy2011@163.com
-
* @date 2011-11-18
-
*/
-
public class StaticParams {
-
-
private static int NUM_A = getA();
-
private static int NUM_B = getB();
-
private static List<String> LIST_A = getListA();
-
-
private StaticParams() {
-
System.out.println("初始化构造方法");
-
}
-
-
public static StaticParams getInstance() {
-
return new StaticParams();
-
}
-
-
private static int getA() {
-
System.out.println("初始化A");
-
return 10;
-
}
-
-
private static int getB() {
-
System.out.println("初始化B");
-
return 20;
-
}
-
-
private static List<String> getListA() {
-
System.out.println("初始化List");
-
return new ArrayList<String>();
-
}
-
-
public static void main(String[] args) {
-
StaticParams.getInstance();
-
}
-
}
运行该程序,输出结果如下:
调整静态变量NUM_A和NUM_B的声明顺序,其他逻辑不变
然后再次运行该程序,输出结果如下:
说到这,想必聪明的程序员就想到问题原因了。即在某个静态变量的初始化还未执行之前就使用该静态变量。为了模拟该问题产生原因,我们修改上面的代码成一个单例模式,具体代码如下:
-
/**
-
*
-
*/
-
package com.mhy.oo.statics;
-
-
import java.util.ArrayList;
-
import java.util.List;
-
-
/**
-
* @author mhy2011@163.com
-
* @date 2011-11-18
-
*/
-
public class StaticParams {
-
-
private static StaticParams sp = buildStaticParams();
-
-
private static int NUM_A = getA();
-
private static int NUM_B = getB();
-
private static List<String> LIST_A = getListA();
-
-
/**
-
* 私有化构造方法
-
*/
-
private StaticParams() {
-
System.out.println("初始化构造方法");
-
}
-
-
/**
-
* sp的声明在其他几个静态变量之前
-
*
-
* @return
-
*/
-
private static StaticParams buildStaticParams() {
-
if (null == sp) {
-
sp = new StaticParams();
-
}
-
int result = NUM_A * NUM_B; // 基本类型有默认值,此处不会报错,但结果不正确
-
System.out.println("result is :" + result);
-
LIST_A.add("abcd"); //此时LIST_A还未初始化,到此有异常
-
return sp;
-
}
-
-
/**
-
* 获取StaticParams实例
-
*
-
* @return
-
*/
-
public static StaticParams getInstance() {
-
return sp;
-
}
-
-
private static int getA() {
-
System.out.println("初始化A");
-
return 10;
-
}
-
-
private static int getB() {
-
System.out.println("初始化B");
-
return 20;
-
}
-
-
private static List<String> getListA() {
-
System.out.println("初始化List");
-
return new ArrayList<String>();
-
}
-
-
public static void main(String[] args) {
-
StaticParams.getInstance();
-
}
-
}
-
在上面的例子中,sp变量初始化中使用到的其他的变量,但其他的静态变量还未初始化,故而在sp初始化时就会产生上面的异常,运行上面的程序就可以在控制台看到如下异常信息:
说到这里,想必大家在编程过程中就知道如何来避免该异常信息的产生了吧。
java.lang.ExceptionInInitializerError异常分析的更多相关文章
- java.lang.ExceptionInInitializerError异常
今天在开发的过程中,遇到java.lang.ExceptionInInitializerError异常,百度查了一下,顺便学习学习,做个笔记 静态初始化程序中发生意外异常的信号,抛出Exception ...
- java.lang.UnsupportedOperationException 异常分析
今天将一个数组转换成 List 然后进行 remove 操作时却抛出 java.lang.UnsupportedOperationException 异常. String pattern = &quo ...
- java.lang.ArrayIndexOutOfBoundsException异常分析及解决
这是一个非常常见的异常,从名字上看是数组下标越界错误,解决方法就是查看为什么下标越界. 下面是一个错误示例: Exception in thread "main" java.lan ...
- java.lang.ArrayIndexOutOfBoundsException 异常分析及解决
参考:http://blog.csdn.net/javaeeteacher/article/details/4485834 这是一个非常常见的异常,从名字上看是数组下标越界错误,解决方法就是查看为什么 ...
- “java.lang.NullPointerException”异常分析
1.父类定义的某个属性,没有被子类使用,或者在子类中,又重新定义一次. 2.因为调用了一个object的方法,且此object的reference为null:比如说:String a=null; // ...
- 记一次java.lang.NoClassDefFoundError异常
前阵子做了个评论过滤敏感词的功能,本地测试没有任何问题,然后就部署到线上服务器,通知相关人员线上测试.大约过了十来天,那货和我说接口出问题了,当时一脸懵逼,用了十来天突然出问题了???好吧,出问题了咱 ...
- java.lang.ExceptionInInitializerError
java.lang.ExceptionInInitializerError at com.csdhsm.compiler.test.DevTest.testReadInput(DevTest.java ...
- android java.lang.ExceptionInInitializerError
11-08 13:36:05.108: E/AndroidRuntime(5318): java.lang.ExceptionInInitializerError 11-08 13:36:05.108 ...
- springboot下jar包方式运行Caused by: java.lang.ExceptionInInitializerError: null
idea调试过程中不会出现此问题,异常如下 org.springframework.beans.factory.BeanCreationException: Error creating bean w ...
随机推荐
- log4j配置文件及nutch中的日志配置 分类: B1_JAVA 2015-02-17 10:58 483人阅读 评论(0) 收藏
吐槽几句,log4j的坑啊.... (1)CLASSPATH中不能有多个log4j的版本本,否则有有奇形怪状的NoSuchMethod, NoSuchFiled, NoClassDefineFound ...
- Android 解决RecyclerView删除Item导致位置错乱的问题
RecyclerView的刷新分为内容变化和结构变化,结构变化比如remove和insert等并不会导致viewholder的更新,所以有时候我们使用 notifyItemRemoved(positi ...
- FZU《C语言程序综合设计》
一年前的玩意. 老是有人找我要..一年前写得这么搓都不敢拿出来.... 但是好多人要啊.....直接发blog,省得下次还要发压缩文件.. 就不要吐槽我代码烂了,我也觉得很烂,至少现在看来确实很烂.. ...
- android 消息系统Handler、MessageQueue、Looper源代码学习
android消息系统 总体框架如图所看到的 在安卓的消息系统中,每一个线程有一个Looper,Looper中有一个MessageQueue,Handler向这个队列中投递Message,Looper ...
- 【例题 6-7 UVA - 122 】Trees on the level
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 二叉树的话,直接用数组存就好了. 写个bfs记录一下答案. [代码] #include <bits/stdc++.h> ...
- 【例题5-7 UVA - 136】Ugly Numbers
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 每个丑数x,都能生成3个丑数2x,3x,5x 则我们以1作为起点. 生成丑数. 每次取出set里面最小的那个数. 然后用它去生成其他 ...
- java项目中VO和DTO以及Entity,各自是在什么情况下应用的
j2ee中,经常提到几种对象(object),理解他们的含义有助于我们更好的理解面向对象的设计思维. POJO(plain old java object):普通的java对象,有别于特殊的j ...
- [Nuxt] Add Arrays of Data to the Vuex Store and Display Them in Vue.js Templates
You add array of todos to the store simply by adding them to the state defined in your store/index.j ...
- 14、USB摄像头(V4L2接口)的图片采集
参考网站http://www.cnblogs.com/surpassal/archive/2012/12/19/zed_webcam_lab1.html 一.一些知识 1.V4L和V4L2. V4L是 ...
- 26、驱动调试之根据oops信息和堆栈确定出错的代码
a.驱动作为模块:1. 根据pc值确定该指令属于内核还是外加的模块pc=0xbf000018 它属于什么的地址?是内核还是通过insmod加载的驱动程序?先判断是否属于内核的地址: 看System.m ...