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初始化时就会产生上面的异常,运行上面的程序就可以在控制台看到如下异常信息:

说到这里,想必大家在编程过程中就知道如何来避免该异常信息的产生了吧。


  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
android. java.lang.ExceptionInInitializerError是一个Java运行时异常,表示类初始化时发生的错误。 当一个类被加载并准备进行初始化工作时,如果其中的静态代码块或静态成员变量的初始化过程中发生异常,就会抛出ExceptionInInitializerError异常。这个异常会导致类的初始化失败,从而使得该类无法使用。 这个异常通常有两种情况会发生:静态代码块或静态成员变量的初始化过程中出现了异常,或者静态代码块或静态成员变量引用的其他类的初始化过程中出现了异常。 在开发Android应用时,常见的ExceptionInInitializerError异常可能发生在以下情况下: 1. 在静态代码块中引用的其他类未能正确进行初始化,例如在使用数据库时,未能正确加载数据库驱动。 2. 静态成员变量的初始化过程中发生了异常,例如在类的静态成员变量的初始化方法中访问了不存在的资源文件。 当出现ExceptionInInitializerError异常时,应该仔细查看异常的详细信息,以确定具体的错误原因。在解决该异常时,一般需要检查静态代码块的内容、静态成员变量的初始化方法以及相关依赖的类的初始化过程是否正确。可以通过调查相关代码、日志信息和堆栈跟踪来定位并解决问题。 总之,android. java.lang.ExceptionInInitializerError是一个表示类初始化错误的异常,通常发生在静态代码块或静态成员变量的初始化过程中。在出现该异常时,需要仔细分析异常的原因,并进行相应的修复。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值