何时在方法区域中将符号引用替换为内存引用?
答案 0 :(得分:2)
现在已以运行时常量池的形式加载到方法区域的所有符号引用都解析为此JVM加载的实际类型。如果符号引用可以解析但导致定义冲突,则抛出IncompatibleClassChangeError
。如果找不到引用的类,则抛出一个NoClassDefFoundError
,它实际上包装了由试图加载该引用的类的类加载器抛出的ClassNotFoundException
。如果被引用的类引用了自身,则会抛出ClassCircularityError
。解析可以以两种方式之一进行,具体取决于JVM的实现者
渴望:对其他字段,方法或类的所有符号引用现在都已解决。
惰性:将符号引用的解析推迟到首次使用方法之前。这可能会导致引用一个不存在的类的类从不抛出错误(如果此引用永远不需要解析的话)。
看看Chapter 5.4.3.决议的开头,其中明确指出:
Java虚拟机指令anewarray,checkcast,getfield, getstatic,instanceof,invokedynamic,invokeinterface,invokespecial, invokestatic,invokevirtual,ldc,ldc_w,multianewarray,新的, putfield和putstatic对运行时进行符号引用 恒定池。执行任何这些指令都需要 符号引用的分辨率。
直接超类和直接实现的接口(或接口的情况下的超级接口)的解析很早就解决了,并且出于上述字节码指令的目的,符号引用的解析也可以推迟。
答案 1 :(得分:0)
解析阶段是必需的,以便基于JVM实现对引用的类或接口进行第一次解析或一次全部解析。
何时将符号引用替换为方法区域中的内存引用
这是类文件验证的一部分,它与类加载器结合使用,并确保加载的类文件具有正确的内部结构并且保持一致。
类文件验证通过四个不同的过程进行:
第1遍:对类文件进行结构检查
这是在加载类时发生的。检查加载的类的内部结构,以确保可以安全解析。
Paas 2 :语义检查数据类型。
这里的类文件验证程序可确保遵守Java编程语言的语义。
第3遍:字节码验证
在这里执行代表类方法的字节码的数据流分析
第4遍:验证符号引用
这是第4遍,发生了动态链接,无非就是将符号引用解析为直接引用的过程。