- 自己动手写Java虚拟机
- 张秀宏
- 392字
- 2023-01-30 16:12:52
3.2.4 版本号
魔数之后是class文件的次版本号和主版本号,都是u2类型。假设某class文件的主版本号是M,次版本号是m,那么完整的版本号可以表示成“M.m”的形式。次版本号只在J2SE 1.2之前用过,从1.2开始基本上就没什么用了(都是0)。主版本号在J2SE 1.2之前是45,从1.2开始,每次有大的Java版本发布,都会加1。表3-2列出了到本书写作为止,使用过的class文件版本号。
表3-2 class文件版本号
![](https://epubservercos.yuewen.com/09A0BE/4587602903621301/epubprivate/OEBPS/Images/figure_0042_0001.jpg?sign=1739392619-WtUQlPTmEEtgmRoXvAzGWG3p4cd30SCv-0-08c2ec9a58f1a249c7fa75e7c184fdec)
特定的Java虚拟机实现只能支持版本号在某个范围内的class文件。Oracle的实现是完全向后兼容的,比如Java SE 8支持版本号为45.0~52.0的class文件。如果版本号不在支持的范围内,Java虚拟机实现就抛出java.lang.UnsupportedClassVersionError异常。我们参考Java 8,支持版本号为45.0~52.0的class文件。如果遇到其他版本号,暂时先调用panic()方法终止程序执行。下面是readAndCheckVersion()方法的代码。
func (self *ClassFile) readAndCheckVersion(reader *ClassReader) { self.minorVersion = reader.readUint16() self.majorVersion = reader.readUint16() switch self.majorVersion { case 45: return case 46, 47, 48, 49, 50, 51, 52: if self.minorVersion == 0 { return } } panic("java.lang.UnsupportedClassVersionError! ") }
因为笔者使用JDK8编译ClassFileTest类,所以主版本号是52(0x34),次版本号是0,如图3-2所示。
![](https://epubservercos.yuewen.com/09A0BE/4587602903621301/epubprivate/OEBPS/Images/figure_0043_0001.jpg?sign=1739392619-KmoafjE1EiXSfZqOwPVQh5rM2AIH3Y2V-0-9e5ce3f0b17b1cd248e4adabd1d3ebcb)
图3-2 用classpy观察版本号