类加载机制

一、类加载的几个阶段
在这里插入图片描述

1、初始化的条件

以下五种情形会触发类的初始化
1、通过new关键字创建对象 调用类的静态属性(读取、设置等)
2、反射
3、初始化一个类,但父类还没有初始化,要先初始化父类
4、应用程序主类,main方法的类
5、动态语言支持

static final 在编译(准备阶段)的时候就已经确定了,已经编译到各个引用类中了
因为在编译时Javac将会为被static和final修改的常量生成ConstantValue属性

加载阶段

虚拟机需要完成以下3件事情:
1)通过一个类的全限定名来获取定义此类的二进制字节流。
2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
3)在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

验证

是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。但从整体上看,验证阶段大致上会完成下面4个阶段的检验动作:文件格式验证、元数据验证、字节码验证、符号引用验证。

准备阶段

是正式为类变量分配内存并设置类变量初始值的阶段。注意是类变量的赋值,即静态变量,而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在Java堆中。而且这里的赋值是默认值,如int类型的0

但假设上面类变量value的定义变为:public static final int value=123;
编译时Javac将会为value生成ConstantValue属性,在准备阶段虚拟机就会根据ConstantValue的设置将value赋值为123。

解析阶段

是虚拟机将常量池内的符号引用替换为直接引用的过程

符号引用(Symbolic References):符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能够无歧义的定位到目标即可

直接引用:可以是直接指向目标的指针,相对偏移量,一个能间接定位到目标的句柄,使用直接引用时,引用的目标必定已经存在于虚拟机的内存中了

类初始化阶段

程序员真正可以操作的阶段,前面除了加载阶段可以自定义类加载器操作外,其他都是虚拟机主导和控制。变量已经赋过一次系统要求的初始值,而在初始化阶段,则根据程序员通过程序制定的主观计划去初始化类变量和其他资源

初始化阶段是执行类构造器<clinit>()方法的过程。<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static{}块)中的语句合并产生的,编译器收集的顺序是由语句在源文件中出现的顺序所决定的。
<clinit>方法
< clinit > 方法是类的初始化方法,而< init > 方法是对象的初始化方法,
< clinit > 方法只会在类需要被加载时,才会被调用到,除非类被卸载了,不然一般只会被调用一次,而< init > 方法则是只要有初始化对象的操作(除了反序列化和使用 Object 的 clone 方法),就会被调用
<clinit>()方法对于类或接口来说并不是必需的,如果一个类中没有静态语句块,也没有对变量的赋值操作,那么编译器可以不为这个类生成<clinit>()方法。

类加载器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值