首页 > 解决方案 > 为什么 Java 在类加载期间需要解析阶段?

问题描述

符号引用何时被方法区域中的内存引用替换?

标签: javajvm

解决方案


现在以运行时常量池的形式加载到方法区域的所有符号引用都被解析为此 JVM 加载的实际类型。如果可以解析符号引用但导致定义冲突,IncompatibleClassChangeError则抛出 a。如果找不到引用的类,NoClassDefFoundError则抛出 a ,它基本上包装了ClassNotFoundException试图加载此引用的类的类加载器抛出的 a 。如果被引用的类引用了自身,ClassCircularityError则抛出 a。解决方案可能以两种方式之一发生,这取决于 JVM 的实现者

Eager:对其他字段、方法或类的所有符号引用现在都已解析。

懒惰:符号引用的解析被推迟到第一次使用方法。如果永远不需要解析这个引用,这可能会带来一个引用不存在的类的类永远不会抛出错误。

第 5.4.3 章的开头。分辨率,有明确说明:

Java 虚拟机指令 anewarray、checkcast、getfield、getstatic、instanceof、invokedynamic、invokeinterface、invokespecial、invokestatic、invokevirtual、ldc、ldc_w、multianewarray、new、putfield 和 putstatic 对运行时常量池进行符号引用。执行任何这些指令都需要解析其符号引用。

直接超类和直接实现的接口(或接口情况下的超接口)的解析发生在早期,并且出于上述字节码指令的目的而对符号引用的解析可以推迟。


推荐阅读