【问题标题】:JVM Constant Pool EntriesJVM 常量池条目
【发布时间】:2016-01-23 21:06:08
【问题描述】:

查看在某些类上运行 javap 的输出,我遇到了以下奇怪现象:

某些类的常量池包含诸如

之类的条目
#33 = Utf8               Code
#34 = Utf8               LocalVariableTable
#35 = Utf8               StackMapTable
#36 = Utf8               MethodParameters

为什么这些常量会出现在常量池中?

【问题讨论】:

  • 这些常量是否在任何地方使用?提示,提示?
  • 它们是各种属性的名称,例如LocalVariableTable,但我不明白为什么这些必须是UTF-8字符串而不是简单的数字ID。
  • 你的意思是像34 吗?使用命名字段使格式更易于扩展和理解。
  • 您已经自己回答了这个问题。这些是与JVMS §4.7 对应的类属性名称。除了预定义的属性之外,还可以有自定义属性,并且将来可能会出现新的属性,因此文本名称似乎更适合。
  • 扩展是关键,正如 JVMS 4.7.1 中所解释的那样:Two attributes that are intended to be distinct, but that happen to use the same attribute name and are of the same length, will conflict on implementations that recognize either attribute. Attributes defined other than in this specification must have names chosen according to the package naming convention described in The Java Language Specification, Java SE 7 Edition (JLS §6.1). 你不能用数值来做到这一点。

标签: java jvm jvm-bytecode


【解决方案1】:

以下常量

#33 = Utf8               Code
#34 = Utf8               LocalVariableTable
#35 = Utf8               StackMapTable
#36 = Utf8               MethodParameters

attributes 的名称。

对于所有属性,attribute_name_index 必须是类常量池中的有效无符号 16 位索引。 attribute_name_index 处的 constant_pool 条目必须是表示属性名称的 CONSTANT_Utf8_info 结构(第 4.4.7 节)。

你提到的属性有以下功能:

  • Code 属性包含 Java 虚拟机指令和方法的辅助信息,包括实例初始化方法或类或接口初始化方法。
  • 调试器可以使用LocalVariableTable 属性 [...] 在方法执行期间确定给定局部变量的值。
  • 在类型检查验证过程中使用StackMapTable属性
  • MethodParameters 属性记录有关方法的形式参数的信息,例如它们的名称。

【讨论】:

    猜你喜欢
    • 2014-06-01
    • 1970-01-01
    • 2015-09-20
    • 2019-10-20
    • 2022-01-17
    • 1970-01-01
    • 2018-06-28
    • 2016-11-18
    • 2019-05-05
    相关资源
    最近更新 更多