JVM类格式:为什么`constant_pool_count`比它大#34;应该"是?

时间:2014-05-15 09:48:30

标签: java jvm

JVM class file format使用constant_pool_count来指定班级常量池的大小:

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

constant_pool_count定义为

  

constant_pool_count项的值等于constant_pool中的条目数加上一个

为什么是这个"中指定的计数加上一个"方式而不仅仅是等于常量的数量?同时,interfaces_countfields_countmethods_countattributes_count似乎不遵循这种模式。

一些猜测:

  • 它可能与实现最佳字节对齐有关
  • 也许它是JVM中其他地方特定设计决策的工件
维基百科上的

更新: This section并没有做太多澄清:

  

由于在文件格式开发期间做出了历史性选择,常量池表中的常量数实际上与表之前的常量池计数不同。首先,表从1(而不是0)开始索引,但计数实际应该被解释为最大索引加1。[3]此外,两种类型的常量(长和双)占用两个连续的槽在表中,虽然第二个这样的插槽是一个永远不会直接使用的幻像索引。

第二部分解释了为什么计数不一定等于常数的数量,如果它们中的任何一个恰好是longdouble,但它仍然不清楚为什么"加上一个"如果它们从数组长度中减去它,则与基于1的索引有任何关系。

1 个答案:

答案 0 :(得分:1)

因为constant_pool_count本身包含在constaint_pool(第一个常量)中。这在逻辑上是constaint_pool [0] == constant_pool_count。

但是constant_pool_count是ClassFile结构中的一个字段,constant_pool数组不再需要包含它。

所以从constant_pool数组中删除constant_pool_count,constant_pool数组的长度将是constant_pool_count - 1.

  

删除:

     

BTW:你可以注意到,constant_pool_count是u2,即   constant_pool条目是cp_info(u1 + u1 = u2),u2和cp_info是   等长结构的长度。

将u2视为{u1; u1 [1]},类似于cp_info {u1; U1 []}。