为什么常量池(在 Java 类文件中)从 1(而不是 0)开始索引?保留的 constant_pool[0] 条目是做什么用的?

Why is the constant pool (in Java classfile) indexed from 1 (and not 0)? What is the constant_pool[0] entry reserved for?

从 JVM 规范 (Chapter 4.1 "The ClassFile structure") 中指出 "The constant_pool table is indexed from 1 to constant_pool_count - 1."

我很好奇他们为什么要跳过 [0] 以及此条目的用途。

没有预留条目。 “[I]indexed from 1”表示常量池中的第一个条目对应于索引 1,因此没有 constant_pool[0]。相反,有一个保留的 index, 0,它肯定不是常量池中的有效索引。

该保留索引的记录用途似乎很少见,但至少第 4.7.24 节指定了一种用途:方法参数的名称由常量池中的索引表示,对于未命名的参数,该索引给出为0.

另请注意,名称 constant_pool_count 具有误导性。规范明确指出常量池中只有 constant_pool_count - 1 个条目(参见 4.1 节顶部的结构声明,并与其他一些成员进行比较)。

他们跳过了索引 0,因此它可用于您通常引用常量池条目但想要指示 "nothing" 的情况。它是相当于空指针的常量池。

索引 0 最显着的用途是 "catch all" 异常处理程序。异常处理程序可以指向它要处理的 class 个异常的常量池条目,或者只使用索引 0 来捕获所有内容(这等同于捕获 java/lang/Throwable)。实际上,编译器将生成捕获所有异常处理程序以实现 finallysynchronized 块,以及 try 资源的清理部分等。

索引 0 的其他用途包括:

  • java/lang/Object
  • 的超级class
  • 没有名称的参数名称
  • classes 的外部 class 不是另一个 class 的成员(即顶级 classes,本地 classes,和匿名 classes)
  • 匿名的内部名称classes
  • 未立即包含在方法中的 class 的封闭方法
  • 没有版本信息的模块的版本信息
  • 没有依赖信息的模块的依赖关系