JAVA字节码常量池中常量编号的疑问

一.问题描述

最近在解析JAVA字节码的时候,发现常量池中常量编号不连续了,导致解析程序经常NPE,然后仔细测试了一下,发现常量类型如果是Long或者Double的话,就会导致常量池中常量的编号不连续了。

假如当前常量类型是Long的话,并且当前常量编号是N,此时如果还有下一个常量的话,下一个常量的编号就是N+2不是N+1了。

字节码常量池中常量的编号

此时我们发现编号为2的常量是Long类型,结果下面一个常量的编号变成4了,为什么不是3?同时编号为5的常量是Double类型,结果下面一个常量的编号变成7了,为什么不是6?

从上面的分析暂时可以得出的结论是:Long或者Double类型的常量在常量池中占据两个常量的编号,这个是为什么呢?

二.相关解释

一开始以为这里的编号可能不是按照自然顺序来的,或者是相对与什么的偏移量,因为方法的字节指令前面的编号就是字节码数组中的偏移量。后面查找了一下JVM规范,发现这是一个Class文件的规范定义。

JVM常量池规范

而且已经在规范里面吐槽过了。因此在解析常量池中常量编号的时候不能一直按照自然顺序单调递增,如果常量是Long或者Double类型的话,需要跳过一个常量的编号。