JAVA 类加载方式(loadClass、forName)

Java的两种类加载方式

一 :隐式加载

通过直接new对象的方式加载,再java运行过程中发现new关键字,会隐式调用类加载器。这种方式可以调用类的空参和带参构造

二 :显示加载

通过loadClassforName这种加载方式需要通过newInstance方法生成对象的实例,这种方式不能调用带参构造,调用带参构造需要反射调用newInstance方法

loadClass和forName的区别

首先了解一下类装载的过程

1 加载 将类的class字节码文件生成class对象
2 连接

连接分三步
1 校验 验证字节码文件的安全性
2 准备 为类变量分配内存空间 并设置初始值 类变量随类型信息存放在方法区中
3 解析 JVM常量池内符号引用转化为直接引用

3 初始化 执行类变量赋值 和静态代码块

LoadClass源码

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
传入的是fasle 里面调用的resolveClass是不会执行的 我们进入看看这个方法的作用
在这里插入图片描述
这个方法是用来确认是否连接这个类的 默认是false说明 loadClass得到的class对象只完成了类装载过程的第一步加载

我们举个例子

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
也就是说forName会执行Static代码 表示forName他会初始化我们这个类

forName源码

在这里插入图片描述
我们找到forName的重载方法 在这里插入图片描述

forName得到的class是已经完成初始化的

是否在类装载的时候连接是通过initialize属性 默认是true

loadClass得到的class是还没有完成连接的

是否连接通过resolveClass 属性 默认false

列举一个forName的使用场景

连接MySQL数据库时
在这里插入图片描述在这里插入图片描述
这个driver他返回Driver对象是靠里面的静态代码块的 因此呢 如果使用ClassLoader 是不行的 需要用forName

loadClass场景

在SpringIOC中,在资源加载器获取要读入的资源的时候以及读取一些bean的配置的时候,是以classpath的方式加载 需要使用ClassLoader.loadClass 方法 。
之所以这样做是和SpringIOC的lazyLoad有关 SpringIOC为了提高加载速度,因此大量使用了延迟加载技术,而使用ClassLoader不需要执行类中的初始化代码 还有连接等步骤,这样做可以加快加载速度,把了类的初始化工作留到类实际使用的时候再去完成。

发布了10 篇原创文章 · 获赞 3 · 访问量 2389

猜你喜欢

转载自blog.csdn.net/qq_44647212/article/details/101910081