我想知道 JVM 中的验证器究竟会在什么情况下启动并检查类。我知道一个这样的例子是当你加载类时,但有时类被加载并稍后被验证。这就是为什么我想确切地知道这种情况何时发生。
1 回答
规范(§4.10)说如下:
Java 虚拟机实现验证每个类文件在链接时满足必要的约束(第 5.4 节)。
§5.4 定义了“链接时间”的确切含义:
如果需要,链接一个类或接口涉及验证和准备该类或接口、其直接超类、其直接超接口及其元素类型(如果它是数组类型)。类或接口中符号引用的解析是链接的可选部分。
该规范允许在何时发生链接活动(以及由于递归,加载)时实现灵活性,前提是维护以下所有属性:
A class or interface is completely loaded before it is linked. A class or interface is completely verified and prepared before it is initialized. Errors detected during linkage are thrown at a point in the program where some action is taken by the program that might, directly
或间接地,需要链接到错误中涉及的类或接口。
例如,Java 虚拟机实现可以选择在使用类或接口时单独解析每个符号引用(“延迟”或“延迟”解析),或者在验证类时一次性全部解析( “渴望”或“静态”分辨率)。这意味着在某些实现中,在初始化类或接口之后,解析过程可能会继续。无论采用哪种策略,在解析期间检测到的任何错误都必须在程序中(直接或间接)使用对类或接口的符号引用的点处抛出。
请注意,事实上,至少 Hotspot 正在按照所述进行延迟初始化(如果 JRockit 和 co 不这样做,我会感到非常惊讶)。
来源:
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.10
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.4