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

Cur*_*ner 4 java jvm .class-file

从JVM规范(第4.1章 “ ClassFile结构”)中可以看出,“ constant_pool表从1索引到constant_pool_count-1”。

我很好奇为什么他们跳过[0],并且该条目保留什么。

Ant*_*ony 6

他们跳过了索引0,因此可以将其用于通常引用常量池条目而又想表示“无”的情况。它等于空指针的常量池。

索引0的最显着用途是用于“捕获所有”异常处理程序。异常处理程序可以指向要处理的异常类的常量池条目,也可以仅使用索引0捕获所有内容(这相当于catch java/lang/Throwable)。在实践中,编译器将产生捕获所有异常的处理来实现finallysynchronized块,并尝试与资源清理部分,除其他事项外。

索引0的其他用途包括:

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

  • 嗯,是的,“同步”和“终于”。但是,正如您所说,这种“捕获所有”习惯用法相当于捕获“java/lang/Throwable”,并且实际上并不需要特殊的编码。如今,它甚至不保存单个字节,因为异常处理程序总是需要一个声明堆栈项的堆栈图,在“catch all”的情况下,它的类型为“java/lang/Throwable”,因此异常处理程序可以引用相同的池条目而不是零。此外,为此目的使用“0xFFFF”而不是零允许“LDC”寻址另一个池条目,但是,这个决定是在四分之一个世纪前做出的…… (3认同)