12、类加载过程

加载

1、通过1类的全路径名来获取定义该类的二进制字节流
2、加载常量到方法区中的常量池
3、在方法区生成一个这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口

**是不是所有的对象都会加载到堆中?**答案是NO。
虚拟机将类加载到方法区的时候,就会在方法区生成一个Java.lang.Class的对象
加载文件来源:ZIP包、WAR包、JSP动态生成、Proxy、从数据库中读取(这种场景相对少)

验证

验证是连接阶段的第一步,这一阶段是确保Class文件中的字节流包含的信息符合当前虚拟机的要求
1、验证Class结构的正确性,如果错误,会抛Java.lang.VerifyError异常

     1)验证魔数:前4个字节(0xCAFEBABE2)主次版本号是否在当前虚拟机的范围内
     3)常量池中的常量是否有不被支持的类型。
     4)Class文件的结构是否齐全,是否有被删减的地方

2、元数据验证(保证元数据信息进行语义校验。验证是否符合Java规范)

	 1)这个类是否有父类(除了Object外,所有的类都应该有父类)
	 2)这个类是否继承了不被允许的类(被final修饰的类)
	 3)这个类不是抽象,是否实现了其抽象父类或接口要求的所有方法
	 4)类中的字段、方法是否与父类产生矛盾
	 (例如覆盖了父类的final字段。或则出现不符合规则的方法重载,例如方法参数都一致,返回类型不同)

3、字节码验证(最复杂的)

	1)保证操作数栈的数据类型与指令代码都能够配合工作
	2)这样的情况:在操作栈放了一个int的数据,使用的时候却是用long来使用
	3)保证跳转指令不会跳转到方法以外的字节码指令上
	4)保证方法体内的转换是有效的。
	例如:把一个子对象赋值给父对象,是有效的。但是把一个父对象赋值给子对象是错误的。

4、符号引用验证(为连接的第三阶段:解析,做准备。主要是校验访问性

	1)符号引用能否通过字符串的全路径名是否能找到该类
	2)符号引用能否通过符合该引用的方法和字段
	3)符号引用中的类、字段、方法的访问性(public,protected,private,default)
	是否可被当前类访问

符号引用的验证主要是为了确保解析阶段能否正常的运行。如果无法通过符号引用验证
则会报错:java.lang.incompatibleClassChangeError的子类:
java.lang.illegalAccessError,java.lang.NosuchFieldError,java.lang.NoSuchMethodError.

准备

准备阶段是正式为类变量分配内存并设置类初始值的阶段。
只为static 变量设置初始值。实例变量(即对象变量,引用变量,非static 变量)将会在对象实例化的时候加载

为static变量设置初始值

public class Test{
     public static int i=123;
}

准备阶段,变量 i 的值是 0.
把变量 i 赋值为 123 是在初始化的时候,才会执行

解析

解析是将常量池中的符号引用转换直接引用的过程,不止解析1次
符号引用以CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Mehodref_info 等类型的常量出现
符号引用与内存布局无关。直接引用与内存布局有关

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值