按照 类加载过程 中的说明,验证是 链接 的第一部。
它主要包括以下几个方面的校验:
- 格式校验(Format Verification):JVM会检查类文件的二进制格式是否符合Java虚拟机规范。这包括检查魔数(Magic Number)是否正确、版本号是否支持当前JVM、常量池中的各种数据类型是否有效等。
- 语义校验(Semantic Verification):JVM会对类文件的字节码进行语义验证,以确保字节码的合法性和安全性。这包括验证字节码中的指令是否合法、操作数是否正确、访问权限是否满足等。例如,JVM会检查方法调用是否符合方法的签名、字段访问是否合法等。
- 字节码校验(Bytecode Verification):JVM会对字节码进行流程分析,以验证类文件的字节码逻辑是否正确。它会检查字节码中的跳转指令是否有效、循环是否正确等。这个过程可以防止字节码中的潜在问题,如死循环、无法到达的代码等。
- 符号引用校验(Symbolic Reference Verification):JVM会检查类文件中的符号引用是否有效。符号引用包括类、方法和字段的引用。JVM会验证这些引用是否可以正确解析,并检查访问权限是否满足。
通过这些校验步骤,JVM可以确保类文件的合法性和安全性。如果类文件未通过任何校验步骤,JVM将抛出VerifyError
或相关的异常,阻止类文件的加载和执行,从而保证了Java程序的稳定性和安全性。
问题 1:implements 和 验证
因为代码里面有混淆,所以某些类的方法会被混淆掉。如果实现了某些接口,理论上是不能被混淆的。
如果混淆掉,就会导致 interfaceA#A -> classA#A
变成 interfaceA#A -> classA#B
所以如果 A
方法变成 B
方法,那么类验证过程中会失败么?
以下为例
提供接口 TestInterface
提供类 TestClass
然后调用,输出日志为
test
那么是否证明该方案没有问题呢?
并不是,当你调用 test()
方法的时候,就会抛出 AbstractMethodError()