java中Class.forName 和 ClassLoader.loadClass 的区别

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

猜你喜欢

转载自blog.csdn.net/xiaojin21cen/article/details/87800635