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 ...
随机推荐
- BC 52 div2 A Victor and Machine
简单数学题,把这道题目贴上去的不过为了不想看到这个月写了某个数字篇博客,该数字有点不吉利... 近期没有学习的欲望.. . 集中不了注意力,今天打BC还是做出来一题,尽管涨分了,真心希望能接近cf的水 ...
- 以流的形式接收Http请求
IEnumerable<ReportObject> IHttpReceiveReport.OnPost(System.Web.HttpContextBase context) { //[{ ...
- ES6的基础知识总结
一. ES6 ES6中定义变量使用 let/const let 使用let定义的变量不能进行"变量提升" 同一个作用域中,let不能重复定义相同的变量名 使用var在全局作用域中定 ...
- JS错误记录 - 事件 - 拖拽
错误总结: 1. var disX = 0; 现在window.onload里声明变量,而不是在事件oDiv.onmousedown里面声明并赋值. 对于这个还不是很明白. 2. onmoused ...
- (转)rman中关于archivelog操作
转自:http://www.xifenfei.com/1609.html RMAN> list backup of archivelog all;列出所有archive log 备份 RMAN& ...
- 安装后,挂载c盘失败
现象: 安装后,window C盘mount失败 错误内容如下: Error mounting: mount exited with exit code 13: ntfs_attr_pread_i: ...
- 发布一个stl标准库容器类(vector/list)的安全删除方法
话不多说,看代码. #include <functional> #ifndef ASSERT #include <cassert> #define ASSERT assert ...
- Learn from Architects of Buildings
 Learn from Architects of Buildings Keith Braithwaite Architecture is a social act and the material ...
- Mac OS X Kernel Basic User Credentials
User Credentials In order to understand security in OS X, it is important to understand that there a ...
- [TypeStyle] Load raw CSS in TypeStyle
TypeStyle tries to be an all in one CSS in JS management solution so you can always fall back to raw ...