最近帮同事debug代码的时候发现一个诡异的错误,就是在实例化类的时候报错说找不到类。而在项目目录的class文件夹中明显可以看到类的存在。经过分析发现是由于类中的一段static方法异常导致类加载失败。在此通过一个简单的示例记录这个错误。
该段static块在实例化一个json对象时抛出一个运行时异常。在StaticTest类中我们调用Employee类的一个静态方法,发现命令行中输出:
既在类的加载过程中出现错误,导致调用static方法Work错误。因为java虚拟机对于类的加载遵循一定的步骤,类在第一次使用时才被加载,并且static方法在加载类时只执行一次。如果类的加载失败那么就不能使用类中的任何方法,也不能实例化对象。
在console中输出:
package exercise.java.example;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
public class Employee {
public static JSONObject _json=null;
static{
String sjson="{\"boolean\":true,\"null\":null,\"number\":123,\"object\":{\"e\":\"f\",\"string\":\"Hello World\"}";
try {
JSONObject json=new JSONObject(sjson);
_json=json;
} catch (JSONException e) {
throw new RuntimeException(e.getMessage());
}
}
public Employee() {
super();
System.out.println("Instance....");
}
String name;
String title;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public static void Work(){
System.out.println("I am working!");
}
}
package exercise.java.example;
public class StaticTest {
public static void main(String[] args){
StaticTest st=new StaticTest();
Employee.Work();
try {
Class.forName("exercise.java.example.Employee");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
代码中包括两个类,一个Employee类,一个测试类StaticTest。
在Employee类中有段static块:
public static JSONObject _json=null;
static{
String sjson="{\"boolean\":true,\"null\":null,\"number\":123,\"object\":{\"e\":\"f\",\"string\":\"Hello World\"}";
try {
JSONObject json=new JSONObject(sjson);
_json=json;
} catch (JSONException e) {
throw new RuntimeException(e.getMessage());
}
}
该段static块在实例化一个json对象时抛出一个运行时异常。在StaticTest类中我们调用Employee类的一个静态方法,发现命令行中输出:
Exception in thread "main" java.lang.ExceptionInInitializerError
at exercise.java.example.StaticTest.main(StaticTest.java:6)
Caused by: java.lang.RuntimeException: Expected a ',' or '}' at character 82 of {"boolean":true,"null":null,"number":123,"object":{"e":"f","string":"Hello World"}
at exercise.java.example.Employee.<clinit>(Employee.java:13)
... 1 more
既在类的加载过程中出现错误,导致调用static方法Work错误。因为java虚拟机对于类的加载遵循一定的步骤,类在第一次使用时才被加载,并且static方法在加载类时只执行一次。如果类的加载失败那么就不能使用类中的任何方法,也不能实例化对象。
因此在static块中一定要处理好异常,才能避免一些错误。
如果我们将抛出运行时异常的代码注释掉,程序就能够执行。
package exercise.java.example;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
public class Employee {
public static JSONObject _json=null;
static{
String sjson="{\"boolean\":true,\"null\":null,\"number\":123,\"object\":{\"e\":\"f\",\"string\":\"Hello World\"}";
try {
JSONObject json=new JSONObject(sjson);
_json=json;
} catch (JSONException e) {
//throw new RuntimeException(e.getMessage());
}
}
public Employee() {
super();
System.out.println("Instance....");
}
String name;
String title;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public static void Work(){
System.out.println("I am working!");
}
}
在console中输出:
I am working!