Class.forName 和 classloader 加载类的区别

一、类加载机制

往细了看大致分为 5 个阶段:

(1)加载:java 类运行时候会生成一个 class 字节码文件,加载的过程就是去我们的操作系统寻找这个 class 文件。

(2)链接:这个过程就是把 class 文件加载到 java 虚拟机。

(3)初始化:在虚拟机中根据 class 文件进行初始化。

(4)使用:这个过程大家都明白。

(5)卸载:使用完了,java 虚拟机进行清理。

对于 class.forName 和 classloader 来说针对的就是第一个过程,也就是加载过程。不过这俩虽然有一定的相似性,但是区别还是挺大的。

二 分析 Class.forName () 和 ClassLoader.loadClass

我们使用代码,先看看如何使用。注意包的范围,避免加载不了。

第一步:定义 User 类

第二步:测试

我们在上面的 test 方法中,使用了两个加载方法。现在我们测试一下:

是不感觉有点区别。现在是先给出一个大体的使用,下面我们分析一下他们的区别。

二、区别

1、class.forName

class.forName () 前者除了将类的.class 文件加载到 jvm 中之外,还会对类进行解释,执行类中的 static 块。注意这里的静态块指的是在类初始化时的一些数据。但是 classloader 却没有,想要弄清楚这个原因,还是直接到源码中看看。

在这个源码中我们会发现,其实底层真正实现的是 forName0 方法,那这几个参数又是什么意思呢?

(1)className:表示我们要加载的类名

(2)true:指 Class 被加载后是不是必须被初始化。 不初始化就是不执行 static 的代码即静态代码,在这里默认为 true,也就是默认实现类的初始化。

(3)ClassLoader.getClassLoader (caller):表示类加载器,到这你会发现 forNanme 其实也是使用的 ClassLoader 类加载器加载的。

(4)caller:指定类加载器。

Class.forName(className)方法,内部实际调用的方法是  Class.forName(className,true,classloader);

第2个boolean参数表示类是否需要初始化,  Class.forName(className)默认是需要初始化。

一旦初始化,就会触发目标对象的 static块代码执行,static参数也也会被再次初始化。

2、classloader

在上面的案例中我们发现,classloader 并没有初始化静态块,原因最好还是到源码中看。

首先我们先进入到 loadclass 方法中的源码。

public Class<?> loadClass(String name)
    throws ClassNotFoundException {
    return loadClass(name, false);
}

这一步看起来还看不明白,没关系这里真正实现的是内部的 loadclass,我们再跟进去看看。

这个才是真正实现的方法,在这里的步骤其实很简单,大致流程是先判断 class 是否已经被加载,如果被加载了那就重新加载,如果没有加载那就使用双亲委派原则加载。加载的时候并没有指定是否要进行初始化。

所以现在他们的区别基本上很少,总结一下:

(1)class.forName () 除了将类的.class 文件加载到 jvm 中之外,还会对类进行解释,执行类中的 static 块。当然还可以指定是否执行静态块。

(2)classLoader 只干一件事情,就是将.class 文件加载到 jvm 中,不会执行 static 中的内容,只有在 newInstance 才会去执行 static 块。

三  数据库链接为什么使用 Class.forName (className)

static {
    try {
        java.sql.DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
        throw new RuntimeException("Can't register driver!");
    }
}

因为内部调用的是静态代码块去加载的 driver

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值