Appearance
Java版本号
提示
来自deepseek解释
下面系统梳理 Java 版本号与 class 文件版本号的对应关系。
一、Class 文件中的版本号
每个 .class 文件的头 8 个字节中的第 5~8 字节分别记录了 次版本号(minor_version) 和 主版本号(major_version)。
- 主版本号(major):随 JDK 大版本递增。
- 次版本号(minor):通常为
0,仅在少数 JDK 内部更新或一些特殊编译器(如 ECJ)会使用非零值,一般 JVM 实现会忽略或严格要求为 0。
格式:
magic (4B) + minor_version (2B) + major_version (2B)
例如 JDK 8 编译的 class 文件头:CA FE BA BE 00 00 00 34(0x34 = 52)
二、JDK 版本与主版本号对照表
| JDK 版本 | 主版本号(十进制) | 十六进制 |
|---|---|---|
| JDK 1.1 | 45 | 0x2D |
| JDK 1.2 | 46 | 0x2E |
| JDK 1.3 | 47 | 0x2F |
| JDK 1.4 | 48 | 0x30 |
| Java 5 | 49 | 0x31 |
| Java 6 | 50 | 0x32 |
| Java 7 | 51 | 0x33 |
| Java 8 | 52 | 0x34 |
| Java 9 | 53 | 0x35 |
| Java 10 | 54 | 0x36 |
| Java 11 | 55 | 0x37 |
| Java 12 | 56 | 0x38 |
| Java 13 | 57 | 0x39 |
| Java 14 | 58 | 0x3A |
| Java 15 | 59 | 0x3B |
| Java 16 | 60 | 0x3C |
| Java 17 | 61 | 0x3D |
| Java 18 | 62 | 0x3E |
| Java 19 | 63 | 0x3F |
| Java 20 | 64 | 0x40 |
| Java 21 | 65 | 0x41 |
| Java 22 | 66 | 0x42 |
| Java 23 | 67 | 0x43 |
| Java 24 | 68 | 0x44 |
注:从 Java 9 开始,版本号不再采用 1.x 形式,但 class 文件主版本号延续递增。
三、版本号的作用与兼容性规则
向下兼容:高版本 JVM 可以执行低版本编译的 class 文件(但要识别 minor 版本,若 minor 为 0 则无需关心)。
不向上兼容:低版本 JVM 无法加载高版本编译的 class 文件,会抛出
UnsupportedClassVersionError。
例如 JDK 8 不识别 JDK 17(major=61)的 class。查看 class 文件版本:
bashjavap -v MyClass.class | grep "major" # 或 file MyClass.class
四、次版本号(minor_version)的意义
- 早期 JDK 1.1 到 1.2 过渡时,minor 曾用非 0 值表示小的修订,但后来规范建议编译器将其设为 0。
- 某些工具(如 AspectJ)会利用 minor 存储自定义信息,但标准 JVM 通常会忽略或校验。
通常可以认为次版本号总是 0,面试中无需过分深究。
五、补充:JDK 发行版号(如 8u202)
日常说的 JDK 8u202 中的 8 是产品版本(对应 class 版本 52),u202 是更新版本(Update),不影响 class 文件的主版本号。
更新版本只用于修复 bug 或增加少量功能,不会改变字节码格式。
一句话总结:major_version = JDK 大版本号 + 44(从 JDK 1.1 的 45 开始);minor_version 几乎总是 0。
JDK 8 → major=52,JDK 11 → major=55,依此类推。