1、Class.forName()和ClassLoader.loadClass的比较
1.1、 Class.forName(className)
其内部实际调用的方法是 Class.forName(className,true,classloader)
方法:Class.forName0(String className, boolean initialize, ClassLoader loader)
参数:
- className 代表全限定类名
- initialize 表示是否初始化该类,为true是初始化该类
- loader 对应的类加载器
说明:
第2个initialize参数是 boolean类型的,表示类是否需要初始化,Class.forName(className)
默认是需要初始化 。
一旦初始化,就会触发目标对象的 static块代码执行,static参数也也会被再次初始化。
1.2、ClassLoader.loadClass(className)
ClassLoader.loadClass(className,false)
的内部实际调用的方法是
Classloder.loadClass(String name, boolean resolve)
,其参数:
- name 代表类的全限定类名
- resolve 代表是否解析,如果为true,则
解析
该类
说明:
由于 ClassLoader.loadClass(className,false)
的 resolve 是false
,表示不 解析
目标对象。根据上面的 “类加载的过程” https://blog.csdn.net/xiaojin21cen/article/details/79480012 ,不 解析
目标对象,后面的 初始化
步骤也不会执行,那么静态块和静态对象就不会得到执行 。
两者最大的区别
Class.forName()
得到的 Class 是经过 加载
、连接
和 初始化
完成的。
Classloder.loaderClass()
得到的 Class 是只进行 加载
,并没有进行 连接
和 初始化
。
2、举一反三:数据库连接,为什么使用Class.forName(),而不使用ClassLoader.loadClass() ?
例如:Mysql 数据库驱动加载就是使用 Class.froName(“com.mysql.jdbc.Driver”)
下面我们来看看Driver的源代码:
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can\'t register driver!");
}
}
}
从Driver的源码中我们可以看出 Driver 这个类只有一个 static块 ,我们必须执行初始化,才能从static块得到 DriverManager
,所以我们选择只能使用 Class.forName()
。
参考:
java类加载的过程: https://blog.csdn.net/xiaojin21cen/article/details/79480012
分析Class.forName()和ClassLoader.loadClass在数据库连接的应用: https://blog.csdn.net/qq953337446/article/details/79833190