[资料] JVM规范里CONSTANT_*的tag值为2的是啥?

RednaxelaFX 2013-07-31
今天有人问到:
引用
请问java 的class文件的常量池的Constant Type为什么没有值为2的tag?
是有什么特别的用处吗?

确实,看Java SE 7版的JVM规范,里面对常量池项的tag的定义是:
Constant Type Value
CONSTANT_Class 7
CONSTANT_Fieldref 9
CONSTANT_Methodref 10
CONSTANT_InterfaceMethodref 11
CONSTANT_String 8
CONSTANT_Integer 3
CONSTANT_Float 4
CONSTANT_Long 5
CONSTANT_Double 6
CONSTANT_NameAndType 12
CONSTANT_Utf8 1
CONSTANT_MethodHandle 15
CONSTANT_MethodType 16
CONSTANT_InvokeDynamic 18

tag值的范围是[1, 3-12, 15-16, 18]
可以看到中间没有2、13、14、17。

其实这些空缺的号码都曾经存在,但随着研发过程的推进发现它们的设计不够合理,为了避免兼容性问题,直接把这些号码废除掉,然后向后使用更大的号码来放新类型。

在JVM规范的早期版本的草案里是有tag值为2的常量池项的。
参考JVM规范1.0 Beta版(1995-08-21):http://www.vorlesungen.uni-osnabrueck.de/informatik/java/ftp_area/vmspec.pdf.gz
Constant Type Value
CONSTANT_Class 7
CONSTANT_Fieldref 9
CONSTANT_Methodref 10
CONSTANT_InterfaceMethodref 11
CONSTANT_String 8
CONSTANT_Integer 3
CONSTANT_Float 4
CONSTANT_Long 5
CONSTANT_Double 6
CONSTANT_NameAndType 12
CONSTANT_Utf8 1
CONSTANT_Unicode 2


Tag值为2的是CONSTANT_Unicode。它跟CONSTANT_Utf8的关系顾名思义,前者是用Unicode编码,后者是用UTF-8编码(的变种)来存储字符串常量值。当时还不流行把两字节编码叫UTF-16,而就直接叫Unicode。后来发现其实没必要用两个不同的tag来表示几乎一样的东西,就统一到只用UTF-8版了。

Tag值为13、14的两个我忘记是干嘛的了⋯一时也没找到对应的资料。这个回头我要是找到资料了再更新回来。
JavaCard VM(JCVM)的规范里有Tag值为13:
CONSTANT_Package 13

至于17这个是跟JSR 292相关的。可以参考一些老文档看当年的JSR 292设计:
http://cr.openjdk.java.net/~jrose/pres/201106-indy-javadoc-mlvm-old/2010-0722/
CONSTANT_InvokeDynamic 17

Tag为17的CONSTANT_InvokeDynamic后来非正式叫做CONSTANT_InvokeDynamicTrans(或者“CONSTANT_InvokeDynamic/transitional”),主要是为了兼容于一些JDK7早期开发版的代码。
HotSpot VM在JDK7的开发过程中还有过一个 -XX:+AllowTransitionalJSR292 参数专门用来兼容两种版本的JSR 292设计。
vavi 2013-07-31
感谢R大的专业细致的回复...

顺便再问个小白问题,BaseType Character 的 J,Z,L (J表示long integer)这这几种命名比较奇怪,这样命名有什么理由吗?
RednaxelaFX 2013-07-31
vavi 写道
顺便再问个小白问题,BaseType Character 的 J,Z,L (J表示long integer)这这几种命名比较奇怪,这样命名有什么理由吗?

这个的理由我不太清楚。J比较好理解,就是I的后一个字母,正好I表示int,J是后一个字母用来表示更"long"的"int"这样。Z和L我也不知道是为什么选这俩字母。同好奇⋯
IcyFenix 2013-08-01
常量池的tag 13、14,有印象曾经看过哪里的资料,说是JVM本身没用到,但是在JCVM还是KVM还是别的VM中用到了,因此这里先绕开了避免重复。

google了一下没有找到资料支持,姑且当个谣言放在这里,等R大再查查。
Global site tag (gtag.js) - Google Analytics