java学习日记2 class文件检验器

class文件检查器:
和类加载器一起,class文件检查器的作用就是保证装载的class字节码文件具有正确合法的内部结构,因为如果一个具有危险性的class文件被装载到虚拟机中,而且被运行,那么它就有可能导致虚拟机的崩溃.在class文件检查器中,通常有四趟检查.但是在第四趟检查中,还进行了另外一项检查.
第一趟:结构检查
class文件的内部检查,第一步的检查就是要保证这个class文件是一个正确的,符合结构标准的calss文件,主要是对其二进制字节校验.例如,每个class文件必须以同样的4个字节开始:魔数0xCAFEBABE,这个魔数的作用就是让class文件检查器很容易的分辨某个有问题的文件,从而加以拒绝.需要注意的一点是,这一趟扫描工作是在被编译成方法区的内部数据结构之前进行的.只有检验通过,才能被编译成方法区的内部数据结构.第二,三,四趟就不是在二进制数据上进行的,而是在方法区的实现的数据结构上进行的.
第二趟:类型数据的语意检查:
这次检查每个组成部分,确认它们是否是其所属类的实例,它们的结构是否正确.例如方法描述符(它的方法返回类型,参数,参数类型,个数)在class文件中被存储为一个字符串,这个字符串必须符合特定的上下文无关文法。检查器对每个组成部分进行检查的目的之一就是,为了每个方法描述符都是符合特定语法的,格式正确的字符串。另外,class文件检验器检查这个类本身是否符合特定条件,这些都是java编程语言规定的。例如:规定这个类除了Object以外的所有类,都必须有一个超类。在本次检查中,检验器还检查final类有没有被子类化,final方法有没有被覆盖。还要检查常量池条目是否合法,并且常量池的所有索引都必须指向类型的常量池条目。也就是说,class文件检验器在运行时检查一些java语言应该在编译期遵守的强制规定。
第三趟:字节码验证
此趟扫描注意力在字节码上,因此被成为“字节码验证”。java虚拟机对字节流进行数据流分析,这些字节流代表的是类的方法。字节码流:代表了java的方法,它是由被成为操作码的单字节指令组成的序列,每个操作码后都跟着一个或多个操作数。操作数:用于在java虚拟机执行操作码指令时提供所需的额外的数据。执行字节码时,依次执行每个操作码,这就在java虚拟机内构成了执行的线程。每个线程被授予自己的java栈,这个栈由不同的栈帧构成。每个方法调用将获得一个自己的栈帧。栈帧:一个内存片断,其中存储着局部变量和计算的中间结果。操作数栈:在栈帧中,用于存储方法的中间结果的部分。操作码和它的可选的操作数可能指存储在操作数栈的数据,或者存储在方法栈帧中的局部变量中的数据。这样在执行一个操作码时,除了可以使用紧随其后的操作数,虚拟机还可以使用操作数栈中的数据,或局部变量中的数据,或者两者都用。
1)确保操作数栈总是包含正确的数值以及正确的类型。
2)确保每个操作码都有合法的操作数,每个操作码,合适类型的数值位于局部变量中或是操作数栈中。在整个检验过程通过后,可以保证这个字节码流被java虚拟机安全的执行。字节码并试图检验出所有的安全问题。如果那样可能会遇到“停机问题”。
第四趟:符号引用的验证
在动态连接的过程中,class文件中包含的符号引用被解析时所做的检查。在这趟检查中,java虚拟机将追踪引用
1)被验证的class文件
2)被引用的class文件
因此在这趟扫描中可能需要装载新的类。大多数的java虚拟机采用的是延迟装载,即真正使用时才装载。
动态连接是将符号引用解析为直接引用的过程。当java虚拟机执行字节码时,如果它遇到一个操作码,这个操作码第一次使用一个指向另一个类的符号引用,虚拟机就必须解析这个符号引用。
1)查找被引用的类(如果必要的话就装载它)
2)将符号引用替换成为直接引用,再次遇到相同引用无需解析可直接使用。
当某个引用时非法引用时,for example:这个类不能被装载,或者不存在,但是不包含被引用的字段或者方法—–class文件检验器将抛出一个错误。在第四趟的扫描中,如果某个符号引用匹配不到正确的方法,即扫描失败,java虚拟机将抛出一个NoSuchMethodError。
第无趟:二进制兼容
其实这一趟也是在第四次检查中发生的,正因为java动态链接的原因,所以在符号引用的验证过程中,必须也要同时验证引用的类和被引用的了之间是否互相兼容.如果不兼容,例如因为导入jar包不是同一版本,新的版本中的某一个类的方法被修改过,那么就会导致在调用的过程中会发生不兼容,从而抛出NoSuchMethodError错误.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值