前言
java 中使用默认的加载器来加载类主要有两种方式,一种是 Class.forName
,另一种是 loadClass
,这两者都有对应重载方法,默认一个参数时,都接收全限定类名,用于加载类,但是其具体含义不同,一个会执行类初始化,一个不会默认执行类初始化。
Class.forName
Class.forName
有两个重载函数,分别是:Class<?> forName(String className)
和 Class<?> forName(String name, boolean initialize, ClassLoader loader)
,其中 forName(String className)
相当于调用 forName(className, true, loader)
。更进一步讲,使用Class<?> forName(String className)
默认会执行类的初始化动作。
如下所示,执行 Class<?> forName(String className)
后会输出静态方法和静态代码块的内容。
1 | public class TestLoad { |
程序输出如下
1 | ------------static method---------- |
loadClass
loadClass
也有两个重载函数:loadClass(String name)
和 loadClass(String name, boolean resolve)
,其中,loadClass(String name)
相当于调用 loadClass(String name, boolean false)
。更进一步讲,使用 loadClass(String name)
默认不会执行类初始化动作。
如下所示,使用 loadClass(String name)
并不会执行类的静态代码块和静态方法。
1 | public class TestLoad { |
程序输出如下
1 | --------class: class com.guozhchun.load.TestLoad |
总结
Class.forName
和 loadClass
两者都能进行类加载,并且返回 Class<?>
对象,但是Class.forName
默认会执行类初始化动作,loadClass
默认不会执行类初始化动作。在使用上要根据具体特性进行选择,特别是要加载一些第三方类时,可能该类会有静态属性或静态代码块,如果当前虚拟机并不存在该静态代码块中引用的类,那么选择 Class.forName
就可能报错(因为会执行初始化化,会执行静态类代码块,这时候可能要继续加载其他的类,如果该类不存在,那就会报错),此时应该选择 loadClass
会合适点。