Java中的Class.forName()和ClassLoader的loadClass()方法都可以用来对类进行加载。
Class.forName()除了将类的.class文件加载到Java虚拟机中,还会对执行类中的static语句(静态代码块、静态变量赋值触发的语句,不包括静态方法)。
ClassLoader的loadClass()只会将类的.class文件加载到Java虚拟机中,不会执行static语句,只有在调用newInstance()方法才会执行static语句。
Class.forName(name,initialize,loader)方法的initialize参数决定是否执行static语句。当initialize参数为false时,调用newInstance()方法才会执行static语句。
定义测试类public class ClassA {
static {
System.out.println("ClassA静态代码块执行");
}
static ClassA cla = new ClassA();
{
System.out.println("ClassA代码块");
}
}
public class ClassB {
static {
System.out.println("ClassB静态代码块执行");
}
}
测试1
public static void main(String[] args) {
String claNameA = "com.sontin.javasrc.reflection.ClassA";
String claNameB = "com.sontin.javasrc.reflection.ClassB";
ClassLoader loader = ClassLoader.getSystemClassLoader();
try {
System.out.println("Class.forName()加载ClassB");
Class> cla1 = Class.forName(claNameB);
System.out.println("ClassLoader对象loadClass()加载ClassA");
Class> cla2 = loader.loadClass(claNameA);
System.out.println("调用newInstance()");
cla2.newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
运行结果:
从运行结果可以看出Class.forName()加载ClassB后立即运行了ClassB中的static语句,而loadClass()加载ClassA后并未立即执行ClassA中的static语句,而是在调用newInstance()方法后才执行static语句。
测试2public static void main(String[] args) {
String claNameA = "com.sontin.javasrc.reflection.ClassA";
ClassLoader loader = ClassLoader.getSystemClassLoader();
try {
System.out.println("Class.forName(name,initialize,loader)加载ClassA");
Class.forName(claNameA, true, loader);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
当参数为true时的运行结果:
当参数为false时的运行结果(只需更改initialize参数即可,代码省略):
可以看出当参数为false时并未执行ClassA中的static语句。



