问:简单说说 java 的 Class.forName 和 ClassLoader.loadClass 方法的区别?
答:一个 Java 类加载到 JVM 中会经过三个步骤:
装载(查找和导入类或接口的二进制数据)
链接(校验:检查导入类或接口的二进制数据的正确性;准备:给类的静态变量分配并初始化存储空间;解析:将符号引用转成直接引用;)
初始化(激活类的静态变量的初始化 Java 代码和静态 Java 代码块)。
1. 对于 Class.forName 方法来说,Class.forName(className) 方法内部实际调用的方法是 Class.forName(className, true, classloader);
/**
三个参数的含义分别为:
name:要加载 Class 的名字
initialize:是否要初始化
loader:指定的 classLoader
*/
public static Class<?> forName(String name, boolean initialize, ClassLoader loader)
2. 对于 ClassLoader.loadClass 方法来说,ClassLoader.loadClass(className) 方法内部实际调用的方法是 ClassLoader.loadClass(className, false);
/**
两个参数的含义分别为:
name:class 的名字
resolve:是否要进行链接
*/
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
所以通过传入的参数可以知道:Class.forName 方法执行之后,已经对被加载类的静态变量分配完了存储空间,而 ClassLoader.loadClass 方法并没有一定执行完链接这一步;当想动态加载一个类,且这个类又存在静态代码块或者静态变量,而你在加载时就想同时初始化这些静态代码块,则应偏向于使用 Class.forName 方法。