【问题标题】:What sets an "interface name" apart from a "class name"?是什么将“接口名称”与“类名称”区分开来?
【发布时间】: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


【解决方案1】:

你是对的,CONSTANT_Class_info 不会告诉你引用的类型是否是一个接口,除了实际解析类型之外,你只能在当前的类文件中收集关于类型的预期性质的提示,也许检测,当它被不一致地使用时。

除了 CONSTANT_Methodref_info 期望声明的类型不是接口和 CONSTANT_InterfaceMethodref_info 期望它是接口之外,super_class 字段中的类型引用的存在意味着非接口类型,而任何类型都存在于interfaces 数组意味着一个接口。

如果是嵌套类型,您可以查看InnerClasses Attribute,它列出了所有嵌套类型及其访问标志,包括ACC_INTERFACE

此外,每个用作注解的类型在技术上都是一个接口,尽管注解属性不使用CONSTANT_Class_info池项,而是直接引用类型名称和签名字符串(CONSTANT_Utf8_info)。

【讨论】:

  • 感谢您收集的额外提示:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-09
  • 1970-01-01
相关资源
最近更新 更多