在第一步加载完了之后,class文件已经进入虚拟机内存,并形成相关数据结构存储在方法区中。要注意的是,验证过程可以在加载未完全完成时进行。
验证主要是为了确保class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。验证过程主要做以下一些事情:
1. 文件格式验证;魔数,主次版本,常量池是否有不支持的常量类型;指向常量的索引值是否有指向不存在的常量或类型不符的常量。CONSTANT_Utl8_info型的常量是否有不符合UTF8编码的数据;
这一步是基于字节流进行的,经过这步后进入内存的方法区中进行存储。后面三步是基于方法区存储结构进行的
2.元数据验证;是否有父类,是否继承了不能继承的类;不是抽象类的话是否实现了父类/父接口要求实现的所有方法。 类中字段或方法与父类是否产生矛盾。
3.字节码验证;任意时刻操作数栈的数据类型与指令代码那个配合;保证跳转指令不会跳到方法体以外的字节码指令上。保证方法体中的类型转换是有效的
4.符号引用验证;这部分内容在第三大步解析阶段中发生。发生在虚拟机将符号引用转化为直接引用的时候。
主要做:符号引用中通过字符串描述的全限定名是否能找到对应的类;在指定类中是否存在符合方法的字段描述符及简单名称所描述的方法和字段。符号引用中的类,字段和方法的访问性是否被当前类访问。