微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JVM学习系列:类的加载连接阶段

概述

本文仅关注类加载过程中的连接阶段,该阶段又可分为三步:验证、准备、解析。

验证

验证阶段主要是为了保证进入到JVM的二进制信息能够符合当前虚拟机的要求且不会危害虚拟机的安全。
验证主要涉及到下面几个方面:

  • 文件格式验证:
    (1)是否以魔数0xCAFEBABE开头。
    (2)主、次版本号是否在当前虚拟机处理范围之内。
    (3)常量池的常量中是否有不被支持的常量类型(检查常量tag标志)。
    (4)指向常量的各种索引值中是否有指向不存在的常量或不符合类型的常量。
    (5)CONSTANT_Utf8_info型的常量中是否有不符合UTF8编码的数据。
    (6)Class文件中各个部分及文件本身是否有被删除的或附加的其他信息。

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

  • 字节码验证:
    主要目的是通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的。这个阶段将对类的方法体进行校验分析,保证被校验类的方法在运行时不会产生危害虚拟机安全的事件,例如:
    (1)保证任意时刻操作数栈的数据类型与指令代码序列都能配合工作,例如不会出现类似这样的情况:在操作数栈放置了一个int类型的数据,使用时却按long类型来加载入本地变量表中。
    (2)保证跳转指令不会跳转方法体以外的字节码指令上。
    (3)保证方法体中的类型转换是有效的,例如可以把一个子类对象赋值给父类数据类型,但是把父类对象赋值给子类数据类型,甚至把对象赋值给与它毫无继承关系、完全不相干的一个数据类型,则是危险不合法的。

  • 符号引用验证:
    符号引用验证可以看作是类对自身以外(常量池中的各种符号引用)的信息进行匹配性校验,通常需要校验以下内容
    (1)符号引用中通过字符串描述的全限定名是否能够找到对应的类。
    (2)在指定类中是否存在符合方法的字段描述符以及简单名称所描述的方法和字段。
    (3)符号引用中的类、字段、方法的访问性(private、protected、public、default)是否可被当前类访问。

准备

解析

结束语

参考

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐