更多 Java 虚拟机方面的文章,请参见文集《Java 虚拟机》
类的显示加载 VS 类的隐式加载
-
显示加载:
- 通过
Class c = Class.forName("Student");
- 通过 ClassLoader 的
loadClass()
方法,例如:
- 通过
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class c = cl.loadClass("Student");
-
隐式加载:通过
new
,例如Student s = new Student("")
Class.forName() VS ClassLoader.loadClass()
关于 Class.forName()
,其代码如下:
public static Class<?> forName(String className)
throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
其中 forName0()
方法调用中的参数 true
表示要初始化该类。包括:
- 执行静态代码块
- 初始化静态域
关于类的初始化,具体参见 Java 类的加载,链接,初始化
关于 ClassLoader.loadClass()
,其代码如下:
public Class<?> loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
其中 loadClass()
方法调用中的参数 false
表示这个类加载后不需要去链接。
总结
-
Class.forName()
得到的 Class 是已经完成初始化的 -
ClassLoader.loadClass()
得到的 Class 是还没有链接的 - 一般情况下,这两个方法效果一样,都能装载Class
- 如果程序依赖于 Class 是否被初始化,就必须用
Class.forName()
,例如加载 JDBC 的驱动:
Class.forName("com.mysql.jdbc.Driver");