Java类文件规范 - 双重和长表示

时间:2015-12-18 17:58:00

标签: java jvm .class-file

在Java类文件规范中,在long and double representation部分,文档说:

  

CONSTANT_Long_info和CONSTANT_Double_info代表8字节   数字(长和双)常量:

CONSTANT_Long_info {
    u1 tag;
    u4 high_bytes;
    u4 low_bytes;
}

CONSTANT_Double_info {
    u1 tag;
    u4 high_bytes;
    u4 low_bytes;
}
  

所有8字节常量占用constant_pool表中的两个条目   类文件。如果是CONSTANT_Long_info或CONSTANT_Double_info   structure是constant_pool表中索引n处的项,然后是   池中的下一个可用项位于索引n + 2。该   constant_pool索引n + 1必须有效,但被认为是不可用的。

我怀疑索引tag中constant_pool中的n+1条目是什么。

2 个答案:

答案 0 :(得分:1)

索引n+1没有标记,因为索引n+1没有常量池条目。它就像索引0.它没有数据,它直接跳到下一个条目。

答案 1 :(得分:0)

通过反复试验,以及tassos-bassoukos的帮助评论,我找到了解决方案。如果在索引n处找到常量长或双, n+1处的索引不是usd,只是

我将用代码显示:

List<Constant> constants = new ArrayList<>();
byte[] bytecode = ... // reads the class byte code
int constantPoolCount = getConstantPoolCount(bytecode);
int offset = getConstantPoolStartOffset(bytecode);

for(int i = 1; i < constantPoolCount; i++){
  int tag = bytecode[offset];
  offset++;

  if(tag == LONG_CONSTANT_TAG) {
    byte[] highBytes = Arrays.copyOfRange(bytecode, offset, offset+4);
    offset += 4;
    byte[] lowBytes = Arrays.copyOfRange(bytecode, offset, offset+4);
    offset += 4;

    ConstantLong c = new ConstantLong(highBytes, lowBytes);
    constants.add(c);

    // because we are at CONSTANT LONG, the entry at n+1 is not used
    constants.add(null);
    i++;

  } else if(tag == DOUBLE_CONSTANT_TAG) {
    ... // performs the same, like LONG_CONSTANT_TAG
  }

  // read more entries without skip indexes.

}

请注意,constants列表从零开始编制索引,constant_pool字节码中的条目从1开始编制索引。

相关问题