我已经使用ClassLoader编写了我想加载的小java类。
public class ClassLoadingObj {
public ClassLoadingObj(){
System.out.println("---instantiating ClassLoadingObj ");
}
static{
System.out.println("---Loading ClassLoadingObj");
}
}
但是当我执行以下代码时:
ClassLoader.getSystemClassLoader().loadClass("com.st.classLoader.ClassLoadingObj");
我发现静态块没有被执行。我的问题是,如果使用loadClass()
方法加载一个类,为什么静态块与实例化静态块总是被执行的类相比不会被执行。
答案 0 :(得分:3)
实际上,当类初始化时会执行静态块,并且它与已加载略有不同。
在已初始化类已链接之前,之前已加载,因此有3个(或4个,包括未加载)状态班级。
Here很好地描述了它是如何工作的以及对一个类进行初始化的要求。
摘录:
Java虚拟机规范提供了实现 类和接口加载和链接的时间灵活性, 但严格定义初始化的时间。所有实施 必须在第一次有效使用时初始化每个类或接口。该 以下六种情况有资格作为有效用途:
- 创建一个新的类实例(在字节码中,执行新指令。或者,通过隐式创建, 反思,克隆或反序列化。)
- 调用类声明的静态方法(在字节码中,执行invokestatic指令)
- 使用或分配由类或接口声明的静态字段,但最终和初始化的静态字段除外 通过编译时常量表达式(在字节码中,执行 一个getstatic或putstatic指令)
- 在Java API中调用某些反射方法,例如类Class中的方法或类中的类 java.lang.reflect包
- 类的子类的初始化(类的初始化需要事先初始化其超类。)
- 在Java虚拟机启动时将类指定为初始类(使用main()<方法)
答案 1 :(得分:0)
java中有两种类加载器。也许您使用的ClassLoader是 java.lang.ClassLoader,但系统不会使用此ClassLoader。你可以试试 com.sun.org.apache.bcel.internal.util.ClassLoader.getSystemClassLoader(),它将执行 静态块。您可以参考此更多信息 页面(http://en.wikipedia.org/wiki/Java_Classloader#Class_Loaders_in_JEE)