【发布时间】:2019-01-26 16:32:57
【问题描述】:
在 java 8 规范的paragraph 4.4.2 中(类似地在其他一些地方)提到了它
类索引
class_index 项的值必须是 constant_pool 表的有效索引。该索引处的 constant_pool 条目必须是 CONSTANT_Class_info 结构(第 4.4.1 节),表示具有字段或方法作为成员的类或接口类型。
CONSTANT_Methodref_info 结构的 class_index 项必须是类类型,而不是接口类型。
我环顾四周,但据我所知,仅凭字节码是不可能区分接口类型和类类型的,即在运行时针对类加载器解析命名类/接口之前实际检查此要求.
我的假设是否正确,还是我错过了一种方法来单独检查类文件中的单个 CONSTANT_Class_info 的此要求?
【问题讨论】:
-
我认为这是正确的。类
com.pany.A的类文件只包含类/接口com.pany.B的名称。如果不阅读类/接口com.pany.B的类文件,您将无法确定com.pany.B是类还是接口。但是如果不阅读com.pany.B的类文件,您也无法验证上述方法是否存在/是否有效 -
tag字段读取有什么问题?它具有 CONSTANT_Fieldref、CONSTANT_Methodref 或 CONSTANT_InterfaceMethodref 的值,具体取决于特定的信息对象。这就是你要找的吗? -
@Progman 这就是我现在计划做的事情:如果 Class_info 被 Methodref/InterfaceMethodref/etc 引用,则在内部用“interface”或“class”标记 Class_info...因为措辞我很困惑,认为信息是重复的,并且在其他地方明确可用,这就是我问的主要原因。
-
我猜编译器会在构建时知道。如果事情发生变化并且入口指向的名称现在是一个接口,则 VM 将在验证或运行时失败并出现错误。
标签: java language-lawyer jvm-bytecode