类的加载机制

本文深入探讨Java类加载过程,包括加载、连接、初始化等关键步骤,解释了类何时会被加载及初始化,以及动态加载的多种途径。

类的加载机制

Jvm的运行流程

编译为class文件为统一完成,但是class的加载只有在调用时才启用。

跨平台的原因是不同平台的jdk封装了不同平台的指令,将代码解析为对应平台识别的机器指令。

 

类的加载流程图

加载,连接(验证,准备,解析),初始化,使用,卸载

 

加载:查找和导入Class文件

根据全限定类名,将class文件以字节流方式读入方法区,并生成Class对象。

通过一个类的全限定类名,来获取定义该类的二进制字节流;

随后,将该字节流所代表的静态存储结构,转化为方法区的运行时数据结构;

在方法区生成一个java.lang.Class对象,作为方法区内该类的各种数据的访问入口

 

连接

验证:在于确保Class文件的字节流中包含信息符合当前虚拟机要求。

主要包括四种验证,文件格式验证,元数据验证,字节码验证,符号引用验证。

文件格式验证:检验该字节流是否满足class文件格式(例如:开头是魔数,主次版本号是否是当前虚拟机处理范围之内,即是否在次到主之间的版本,高于主的版本不加载(这就是低版本的jdk无法执行高版本jdk的原因),等等),检验过后,执行"加载"部分的第二件事,将数据放入方法区并存储

元数据验证:保证类的元数据信息符合java语言规范(例如:这个类若是普通类,是否实现了其实现接口下的所有类)

字节码验证,确定指令顺序符合逻辑

符号引用验证: 将符号引用转化为直接引用的过程

准备:分配空间以及设置初始值

类中的static变量分配内存(方法区),并设置默认值为0(eg.static int x = 123;//这时候x = 0)。

类中的final变量分配内存(常量池),并设置为期望值(eg.final int y = 456;//这时候y = 456)。

类对象实例创建时,在堆中给实例变量分配内存空间。

解析:将常量池内的符号引用替换为直接引用的过程

Java文件在编译为Class文件时,如对于其他类的引用,此时使用符号引用的方式进行代替,存储在class文件的常量池中;在类加载过程中,解析时,将符号引用转化为指向实际地址的直接引用,并存储在运行时常量池中。

 

初始化:对静态变量,静态代码块执行初始化工作

执行静态块(static{})、初始化static变量(eg.static int x = 123;//"准备"阶段后,x = 0;"初始化"后,x = 123)、执行构造器

发生的时机:外部调用new时启用(或者反射调用类的情况下)

 

使用:使用该类所提供的功能.

卸载:从内存中释放.

代码执行顺序

Static{}以及静态变量按照从上到下顺序执行,静态变量最开始为0后来为1(1,2);类的构造完成(3);执行入口main方法(4),执行main中涉及实例化时,调用构造方法。

 

生成class文件的途径:动态加载

JAR,WAR,EAR包获取

如Applet从网络中获取

如java动态代理技术,在运行时生成

如从jsp文件等其他文件中生成class文件

类什么时候被初始化

创建类的实例,也就是 new 一个对象

反射(Class.forName("com.lyj.load"))

访问某个类或接口的静态变量,或者对该静态变量赋值,或者调用类的静态方法

初始化一个类的子类(会首先初始化子类的父类)

JVM 启动时标明的启动类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值