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_count
,fields_count
,methods_count
和attributes_count
似乎不遵循这种模式。
一些猜测:
更新: This section并没有做太多澄清:
由于在文件格式开发期间做出了历史性选择,常量池表中的常量数实际上与表之前的常量池计数不同。首先,表从1(而不是0)开始索引,但计数实际应该被解释为最大索引加1。[3]此外,两种类型的常量(长和双)占用两个连续的槽在表中,虽然第二个这样的插槽是一个永远不会直接使用的幻像索引。
第二部分解释了为什么计数不一定等于常数的数量,如果它们中的任何一个恰好是long
或double
,但它仍然不清楚为什么"加上一个"如果它们从数组长度中减去它,则与基于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 []}。