使用Class.forName(paramClassName)方法时要注意了,如果被初始化的类paramClassName在类的静态初始化代码中有异常抛出,且未被捕捉,那么该方法执行到此将suspend。
public class Foo {
static {
init();
}
static void init() {
throw new RuntimeException("foo init"); //不建议这样使用
}
}
public class Bar {
public static void main(String[] args) throws Exception {
System.out.println("111");
Class.forName("agent.Foo");
//无法执行到此
System.out.println("222"); }
}
执行结果:
111
Exception in thread "main" java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at agent.Bar.main(Bar.java:17)
Caused by: java.lang.RuntimeException: foo init
at agent.Foo.init(Foo.java:19)
at agent.Foo.<clinit>(Foo.java:15)
... 3 more
通过这个例子,一般来说,为了能够保证虚拟机正常加载和初始化Class字节码(对某些场景,比如Java热部署组件),不建议在静态初始化代码中产生或抛出异常,应该在用户所调用的方法中产生异常,或者,至少也应该延迟在构造函数中抛出。