自己动手写Java虚拟机
上QQ阅读APP看书,第一时间看更新

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文件版本号

特定的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所示。

图3-2 用classpy观察版本号