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
定义为
The value of the
constant_pool_count
item is equal to the number of entries in theconstant_pool
table plus one.
为什么以这种“加一”的方式指定计数而不是等于常量的数量?同时,interfaces_count
、fields_count
、methods_count
和 attributes_count
似乎不遵循这种模式。
一些猜测:
- 它可能与实现最佳字节对齐有关
- 也许它是 JVM 中其他地方的特定设计决策的产物
更新: This section在维基百科上并没有做太多澄清:
Due to historic choices made during the file format development, the number of constants in the constant pool table is not actually the same as the constant pool count which precedes the table. First, the table is indexed starting at 1 (rather than 0), but the count should actually be interpreted as the maximum index plus one.[3] Additionally, two types of constants (longs and doubles) take up two consecutive slots in the table, although the second such slot is a phantom index that is never directly used.
第二部分解释了为什么计数不一定等于常量的数量,如果它们中的任何一个恰好是 long
或 double
,但它仍然不是清楚为什么“加一”与基于 1 的索引有任何关系,如果它们从数组长度中减去它的话。
最佳答案
因为constant_pool_count本身包含在constant_pool(第一个常量)中。这在逻辑上是 constaint_pool[0] == constant_pool_count。
但是constant_pool_count是ClassFile结构体中的一个字段,constant_pool数组就没有必要再包含它了。
因此从 constant_pool 数组中删除 constant_pool_count,constant_pool 数组的长度将为 constant_pool_count - 1。
deleted:
BTW: as you can notice, the constant_pool_count is u2, the constant_pool entries are cp_info(u1+u1=u2), u2 and cp_info are equivelant structure in length.
将 u2 视为 {u1; u1[1]},类似于cp_info{u1; u1[]}.
关于java - JVM 类格式 : Why is `constant_pool_count` one larger than it "should" be?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23674727/