解析

解析阶段是Java虚拟机将常量池内的符号引用替换为直接引用的过程,在Class文件中它以

CONSTANT_Class_infoCONSTANT_Fieldref_infoCONSTANT_Methodref_info等类型的常量出现。

符号引用 & 直接引用

符号引用(Symbolic References):符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,

只要使用时能无歧义地定位到目标即可。符号引用与虚拟机实现的内存布局无关,引用的目标不一定已经加载到

虚拟机内存中。符号引用的字面量形式明确定义在《Java虚拟机规范》的Class文件格式中。

直接引用(Direct References):直接引用是可以直接指向目标的指针、相对偏移量或者是一个能间接定位到目标的句柄。

直接引用是和虚拟机实现的内存布局直接相关的。如果有了直接引用,那引用的目标必定已经在虚拟机的内存中存在。

解析的时机

《Java虚拟机规范》之中未规定解析阶段发生的具体时间,只要求在执行了某些字节码之前,需要先对

它们所使用的符号引用进行解析。

anewarray、checkcast、getfield、getstatic、instanceof、invokedynamic、invokeinterface、

invokespecial、invokestatic、invokevirtual、ldc、ldc_w、multianewarray、new、putfield、putstatic

对同一个符号引用进行多次解析请求是很常见的事情,除invokedynamic指令外,虚拟机实现可以对第一次解析

的结果进行缓存,譬如在运行时直接引用常量池中的记录,并把常量标识为已解析状态,从而避免重复解析。