最初编写JVM时,设计人员在常量池中拥有CONSTANT_Long_info
和CONSTANT_Double_info
结构,占用了2个条目(可能是因为这样您可以按4字节索引常量池)对齐或沿这些线的东西。
但是,根据JVM 10 specification, that has not been changed。
如果进行更改,则需要更改许多代码,这是有道理的,因为JVM应该能够运行为较早的JVM构建的代码,但在我看来,在有条件的情况下它几乎不需要更改确定您是否在处理早期版本的类-与之相关的唯一时间是初始化常量池还是对其进行迭代,这种情况很少发生,反而充满了条件
此外,过去已经引入了更大的重大更改,例如Java 9模块。那么,为什么今天仍然如此?是有架构上的原因,还是到目前为止不值得任何人花费时间?
答案 0 :(得分:2)
就像从Java 1.1到Java 11的大部分更改一样,在字节码格式方面,模块的引入并没有太大变化。对于应用程序逻辑或反射来说,它可能是激进的,而不是对于字节码处理工具而言,只需要稍作扩展即可。
仅当您寻求更大的前景时,才能更改CONSTANT_Long_info
和CONSTANT_Double_info
的逻辑。还改变了long
和double
带有两个局部变量和两个操作数堆栈条目的事实。然后,您将不得不触摸很多代码位置。
但是,无论变化有多大或少,重要的问题是,您从中获得了什么回报?更好的感觉不重要。更改它的主要原因是简化规则,从而简化字节码处理工具。但是,由于这些工具需要条件才能启用仍然存在的较旧类文件的处理,因此无法实现这种优势。实际上,通过这种更改,工具将变得更加复杂。
当您开发一种全新的格式(无论如何仍需要新的工具)时,情况将有所不同。它本来可以作为JMOD格式的一种选择,但是正是开发新工具链的需要才是为什么它没有发生的原因,而当前的JMOD只是一个zip文件,就像旧的jar文件一样。
一个反例是the StackMapTable
attribute,它在开发时没有向后兼容的限制,因此不会对long
和double
项进行两次计数。处理工具的职责是将这些堆栈映射表项转换为对long
和double
值确实使用两个值的堆栈帧项(除非我们正在讨论的是采用另一种方式进行转换的环境)一轮)。