Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么常量池(在Java类文件中)从1(而不是0)索引?常量_池[0]项是为什么保留的?_Java_Jvm_.class File - Fatal编程技术网

为什么常量池(在Java类文件中)从1(而不是0)索引?常量_池[0]项是为什么保留的?

为什么常量池(在Java类文件中)从1(而不是0)索引?常量_池[0]项是为什么保留的?,java,jvm,.class-file,Java,Jvm,.class File,从JVM规范(“类文件结构”)中可以看出,“常量池表的索引从1到常量池计数-1。” 我很好奇他们为什么要跳过[0],这个条目是为什么保留的。没有保留条目。“[I]ndexed from 1”表示常量池中的第一个条目对应于索引1,因此没有任何常量池[0]。相反,存在一个保留索引0,它肯定不是常量池中的有效索引 记录在案的保留索引的使用似乎很少,但至少第4.7.24节指定了一种用法:方法参数的名称由常量池中的索引表示,对于未命名的参数,该索引为0 还请注意,名称常量\u池\u计数具有误导性。规范明确

从JVM规范(“类文件结构”)中可以看出,“常量池表的索引从1到常量池计数-1。”


我很好奇他们为什么要跳过[0],这个条目是为什么保留的。

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

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


还请注意,名称
常量\u池\u计数
具有误导性。规范明确指出,常量池中只有
常量池\u计数-1
项(请参阅第4.1节顶部的结构声明,并与其他一些成员进行比较)。

他们跳过了索引0,以便在通常引用常量池项的情况下可以使用它,而是想表示“什么都没有”。它是与空指针等效的常量池

索引0最显著的用途是“捕获所有”异常处理程序。异常处理程序可以指向它要处理的异常类的常量池条目,或者只使用索引0捕获所有内容(这相当于捕获
java/lang/Throwable
)。实际上,编译器将生成捕获所有异常处理程序,以实现
最终
同步
块以及try with resources的清理部分等

索引0的其他用途包括:

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

使用索引0的还有其他几种情况。最值得注意的是“一网打尽”的异常处理程序。感谢您提供了这一非常清晰和信息丰富的答案!有趣的是,当做出决定时,Java1.0中只存在第一点。因此,第一个常量池索引是为一个角落案例保留的…@Holger Java 1.0有同步块吗?因为这些都是用catch[0]实现的。是的,
已同步
最终
。但是,正如您所说,这种“一网打尽”的习惯用法相当于捕捉
java/lang/Throwable
,并不需要特殊的编码。现在,它甚至不保存一个字节,因为异常处理程序总是需要一个stackmap来声明堆栈项,如果是“catch all”,它的类型是
java/lang/Throwable
,因此异常处理程序可以引用相同的池条目,而不是零。此外,使用
0xFFFF
而不是零可以允许
LDC
处理更多的池条目,但是,这个决定是在四分之一世纪前做出的…