我一直在阅读各种文件的Java字节码,以帮助我理解需要与第三方库集成的项目的.class文件,因为该库没有源代码且文档质量不佳。
出于自己的兴趣,我运行了Apache BCEL库通过我的Maven仓库,以查看更稀有的类和方法属性,例如类型注释是如何使用的以及原因。
我遇到了一个特定jar的问题,它无法解码一个常量字段 - 具体来说是CONSTANT_Utf8_info。这个库是icu4j-2.6.1.jar (com.ibm.icu:icu4j),特别是LocaleElements_zh__PINYIN.class文件。Apache BCEL失败了(以及我自己快速遵守JVMS版本8和9的字节码阅读器),他们都会误读此常量,然后读取下一个字节,该字节评估为不正确的常量标记(0x3C/60)。
尝试在IDE中使用该类进行快速检查失败(无法解析符号)。使用十六进制编辑器调查实际的字节码,显示在该偏移量(0x1AC)处的常量是一个Utf8常量(tag=0x01),长度为0x480E。在文件中向前移动该数量确实在该位置有一个字节0x3C。从视觉上查看文件,我可以看到所讨论的常量在位置0x149BD结束,这使得字符串的实际长度为0x1480E(基本上是位置0x1AC处的前三个字节)。当然,这是不可能的,因为JVM类文件规范具有最大长度为0xFFFF或65535的Utf8常量。该classfile相当老 - 版本46或Java 1.2。
我已经详细研究了规范,并尝试了不同的可能实现(更严格和更宽松),以尝试解析此常量,但它要么无法解析,要么会破坏其他有效的Utf8常量的读取。
那么我的问题是,我错过了什么,还是编译器出了问题,如果是这样的话,我的第二个问题是这种情况如何发生 - 编译器往往会经过相对彻底的检查。最后,Java编译器通常如何管理长度超过65535字节的字符串文字?
出于自己的兴趣,我运行了Apache BCEL库通过我的Maven仓库,以查看更稀有的类和方法属性,例如类型注释是如何使用的以及原因。
我遇到了一个特定jar的问题,它无法解码一个常量字段 - 具体来说是CONSTANT_Utf8_info。这个库是icu4j-2.6.1.jar (com.ibm.icu:icu4j),特别是LocaleElements_zh__PINYIN.class文件。Apache BCEL失败了(以及我自己快速遵守JVMS版本8和9的字节码阅读器),他们都会误读此常量,然后读取下一个字节,该字节评估为不正确的常量标记(0x3C/60)。
尝试在IDE中使用该类进行快速检查失败(无法解析符号)。使用十六进制编辑器调查实际的字节码,显示在该偏移量(0x1AC)处的常量是一个Utf8常量(tag=0x01),长度为0x480E。在文件中向前移动该数量确实在该位置有一个字节0x3C。从视觉上查看文件,我可以看到所讨论的常量在位置0x149BD结束,这使得字符串的实际长度为0x1480E(基本上是位置0x1AC处的前三个字节)。当然,这是不可能的,因为JVM类文件规范具有最大长度为0xFFFF或65535的Utf8常量。该classfile相当老 - 版本46或Java 1.2。
我已经详细研究了规范,并尝试了不同的可能实现(更严格和更宽松),以尝试解析此常量,但它要么无法解析,要么会破坏其他有效的Utf8常量的读取。
那么我的问题是,我错过了什么,还是编译器出了问题,如果是这样的话,我的第二个问题是这种情况如何发生 - 编译器往往会经过相对彻底的检查。最后,Java编译器通常如何管理长度超过65535字节的字符串文字?