类加载的过程之加载与验证(八)

类加载全过程:加载,验证,准备,解析,初始化。

加载阶段

在此阶段,虚拟机要完成三件事:

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

加载阶段既可以使用Java虚拟机里内置的类加载器来完成,也可以由用户自定义的类加载器去完成。

对于数组来说,数组类不由类加载器创建,它由Java虚拟机直接在内存中动态构造出来,但是数组的元素类型还是要有类加载器来完成加载。

一个数组类创建过程遵循以下规则:

  1. 如果数组类型是引用类型,那就递归加载过程去加载这个组件类型,数组将被标识在加载该组件类型的类加载器的类名空间上。
  2. 如果数组的组件类型不是引用类型(如int[] 数组的组件类型为int),Java虚拟机会把数组标记为与引导类加载器相连。
  3. 数组类的可访问性与它的组件的可访问性一致,如果组件类型不是引用类型,它的数组类的可访问性默认为public。
    加载阶段结束后,Java虚拟机外部的二进制字节流就按照虚拟机所定义的格式存储在方法区中。

验证阶段

目的:确保Class文件的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求,保证这些信息被当做代码运行后不会危害虚拟机自身的安全。
验证阶段会完成下面四个阶段的检验动作:文件格式验证,元数据验证,字节码验证,符号引用验证

文件格式验证

验证字符流是否符合Class文件格式的规范,且能被当前虚拟机处理。
可能包括以下验证点:

  1. 是否以魔数0xCAFFEBABE开头(Class文件头)
  2. 主、次版本号是否在当前虚拟机的接受范围之内
  3. 常量池的常量中是否有不被支持的常量类型
  4. 。。。。。。
    这一阶段的目的:保证输入的字节流能正确地解析并存储到方法区之内,格式上符合描述一个Java类型信息的要求。此阶段验证基于二进制字节流,通过后,这段字节流才会进入虚拟机的方法区进行存储,后面的三个阶段都是基于方法区的存储结构上进行的,不会再直接进行读,取字节流了。

元数据验证

第二阶段对字节码描述的信息进行语义分析。
可能的验证点:

  1. 这个类是否有父类(除了 java.lang.Object 之外,所有的都应当有父类)
  2. 这个类的父类是否继承了不允许被继承的类(final修饰的类)
  3. 如果这个类不是抽象类,是否实现了其父类或接口之中所要求实现的所有方法
  4. 类的字段方法是否与父类产生了矛盾
  5. 。。。。。。
    目的:对类的元数据信息进行语义校验。

字节码验证

第三个阶段整个验证过程中最复杂的阶段,目的是通过数据流分析和控制流分析,确定程序语义是合法的,符合逻辑的。第二阶段对元数据信息中的数据类型校验完毕后,这阶段对类的方法体(Class文件中的Code属性)进行校验分析,保证被校验的方法在运行时不会做出危害虚拟机安全的行为。
例如:

  1. 保证任意时刻操作数栈的数据类型与指令代码都能配合工作,例如不会出现类似于“在操作栈放置了一个int类型的数据,使用时却按照long类型来加载本地变量表中”。
  2. 保证任何跳转连接都不会跳转到方法体以外的字节码上
  3. 保证方法体中的类型转换总是有效的
  4. 。。。。。。。
    一个类型中有方法体的字节码没有通过验证,那他一定有问题;通过验证也不一定安全。

符号引用验证

最后一个阶段的校验行为发生在虚拟机将符号引用转化为直接引用的时候,这个转化动作将在连接的第三阶段——解析阶段发生。可以做对类自身以外(常量池中各种符号引用)的各类信息进行匹配性校验,判断该类是否缺少或者被禁止访问它依赖的某些外部类,方法,字段等资源。
校验内容:

  1. 符号引用中通过字符串描述的全限定名是否能找到对应的类
  2. 在指定类中是否存在符合方法的字段描述符及简单名称所描述的方法和字段

目的:确保解析行为正常执行。

验证阶段对虚拟机类加载机制来说,重要却不必要。通过了,其后就对程序运行期没任何影响了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值