Java类加载机制

什么是类加载

        类加载:就是将类的class文件读入内存,并创建一个Java.lang.class对象。类在运行期第一次使用时,首先会被类加载器动态加载至JVM。类的加载过程又分为了五个阶段:加载、验证、准备、解析、初始化。为了方便记忆可以编为一个口诀:家(加载)宴(验证)准备(准备)了西(解析)式(初始化)菜。

类的生命周期被分为了七个阶段:加载、验证、准备、解析、初始化、使用、限载

         接下来我们就具体介绍一下类加载的过程

加载

        “加载”是类加载的第一个阶段,在加载过程中主要完成了以下三件事:

  1. 通过反射获取定义该类的二进制字节流
  2. 将该字节流静态储存结构转换为原空间运行时储存结构
  3. 在内存中生成一个Class对象代表元空间该类各类数据的访问入口

验证

        该步骤是验证类或接口的Class文件中的中的二进制,确保二进制中的信息符合虚拟机规范要求,并且不会危害到虚拟机的自身安全。

准备

        准备阶段是为类变量分配元空间内存并设置默认初始值,类变量指的是static修饰的变量。注:如果类变量是常量,那么不会定义默认初始值,而是直接初始化为表达式定义的值

例:

public static int value=100;//初始值为0

public static final int value=100;//初始值为100

 解析

        解析阶段是将常量池的符号引用替换为直接引用的过程。为了支持Java的动态绑定解析的过程在有些情况下可以在初始化阶段之后执行。

初始化

        初始化是类加载的最后一步,在初始化阶段开始执行Java代码。初始化阶段是虚拟机执行类构造器<clinit>()的阶段,在这个阶段要对类变量再一次赋表达式定义的值。

类加载的时机

        在介绍完类加载的过程之后,我们对类加载的过程有了一个初步的了解,那么类究竟是什么时候加载的呢?要触发什么样的机制才会加载类呢?

主动引用

虚拟机规定在五种情况下必须进行类加载:

  • 当出现new、getstatic、putstatic、invokestatic这些指令时会进行类加载 

new指令:程序创建一个类的实例对象时

getstatic指令:当程序访问类的静态变量时

putstatic指令:当程序给静态变量赋值时

invokestatic指令:当程序调用静态方法时

注:程序访问类的静态常量不会触发类加载机制

  • 当通过反射机制的Class.forName("...")或newInstance()等方法时触发类加载
  • 当虚拟机启动时,该类中包含main()方法时触发类加载
  • 在JDK8中,当接口中的实习类调用了接口的默认方法,如果这个实现类要发生类加载首先会触发接口的类加载

除了以上五种触发类加载的引用类其他引用类都不会触发类加载,被称为被动引用

被动引用

常见被动引用

  • 当子类引用父类的静态字段时,不会触发子类的类加载机制
  • 当通过数组来定义引用类时,不会触发该类的类加载机制
  • 引用常量不会造成定义常量的类加载,因为常量储存在常量池,本质上没有直接引用到定义常量的类

类加载器分类

        类加载器分为:启动类加载器、扩展类加载器。应用程序类加载器

双亲委派模型

        应用程序是由通常是由三种类加载器互相配合,从而实现类加载,除此之外还可以加入自己定义的类加载器。类加载器之间的层次关系,被称为双亲委派模型。该模型要求除了顶层的启动类加载器外,其它的类加载器都要有自己的父类加载器。父子关系是组合关系而不是继承关系。

工作机制:一个类加载器首先将类加载请求转发到父类加载器,只有当父类加载器无法完成时才尝试自己加载。
作用:

  • 使得基础类得到统一,避免冲突
  • 实现热加载,比如Spring Boot DevTools
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雾远望

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值