用javap查看编译版本

Java编译版本解析
我们可以用javap命令查看class文件的编译版本。<wbr style="line-height:25px"><div style="line-height:25px">比如对Worke.class使用javap命令:javap -verbose Worker</div> <div style="line-height:25px">我将看到Worker的反编译结果。其中前几行如下:</div> <div style="line-height:25px"> <div style="line-height:25px"><span style="color:#3366FF; line-height:25px">Compiled from "Worker.java"</span></div> <div style="line-height:25px"><span style="color:#3366FF; line-height:25px">public class com.teleca.robin.Worker extends java.lang.Thread</span></div> <div style="line-height:25px"><span style="color:#3366FF; line-height:25px">SourceFile: "Worker.java"</span></div> <div style="line-height:25px"> <span style="color:#993300; line-height:25px">minor version: 0</span> </div> <div style="line-height:25px"> <span style="color:#993300; line-height:25px">major version: 49</span> </div> <div style="line-height:25px"> <span style="color:#3366FF; line-height:25px">Constant pool:</span> </div> </div> <div style="line-height:25px"> <span style="color:#003366; line-height:25px">上面的</span><span style="line-height:25px; color:rgb(153,51,0)">minor version: 0和</span><span style="line-height:25px; color:rgb(153,51,0)">major version: 49</span><span style="color:#003366; line-height:25px">就是编译</span>Worke.class<span style="color:#003366; line-height:25px">时使用的jdk编译版本号。</span> </div> <div style="line-height:25px">但是它并不是我们所熟悉的jdk版本号(比如jdk1.5)。</div> <div style="line-height:25px">不过我们可以把<span style="line-height:21px; font-family:verdana,sans-serif">从 JDK 1.1 到 JDK 1.7 编译器编译出的 class 的默认 minor.major version 汇总下就知道对应关系了。</span> </div> <div style="line-height:25px"> <span style="line-height:21px; font-family:verdana,sans-serif"></span> <table width="700" align="center" border="1" style="line-height:25px; border-collapse:collapse"><tbody style="line-height:25px"> <tr style="line-height:25px"> <td width="20%" style="line-height:25px"><span style="line-height:25px">JDK 编译器版本</span></td> <td width="30%" style="line-height:25px"><span style="line-height:25px">target 参数</span></td> <td width="25%" style="line-height:25px"><span style="line-height:25px">十六进制 minor.major</span></td> <td width="25%" style="line-height:25px"><span style="line-height:25px">十进制 minor.major</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">jdk1.1.8</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">不能带 target 参数</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 03 00 2D</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">45.3</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">jdk1.2.2</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">不带(默认为 -target 1.1)</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 03 00 2D</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">45.3</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">jdk1.2.2</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">-target 1.2</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 00 00 2E</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">46.0</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">jdk1.3.1_19</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">不带(默认为 -target 1.1)</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 03 00 2D</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">45.3</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">jdk1.3.1_19</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">-target 1.3</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 00 00 2F</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">47.0</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">j2sdk1.4.2_10</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">不带(默认为 -target 1.2)</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 00 00 2E</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">46.0</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">j2sdk1.4.2_10</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">-target 1.4</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 00 00 30</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">48.0</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">jdk1.5.0_11</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">不带(默认为 -target 1.5)</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 00 00 31</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">49.0</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">jdk1.5.0_11</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">-target 1.4 -source 1.4</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 00 00 30</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">48.0</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">jdk1.6.0_01</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">不带(默认为 -target 1.6)</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 00 00 32</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">50.0</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">jdk1.6.0_01</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">-target 1.5</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 00 00 31</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">49.0</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">jdk1.6.0_01</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">-target 1.4 -source 1.4</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 00 00 30</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">48.0</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">jdk1.7.0</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">不带(默认为 -target 1.6)</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 00 00 32</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">50.0</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">jdk1.7.0</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">-target 1.7</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 00 00 33</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">51.0</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">jdk1.7.0</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">-target 1.4 -source 1.4</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 00 00 30</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">48.0</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">Apache Harmony 5.0M3</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">不带(默认为 -target 1.2)</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 00 00 2E</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">46.0</span></td> </tr> <tr style="line-height:25px"> <td style="line-height:25px"><span style="color:#003366; line-height:25px">Apache Harmony 5.0M3</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">-target 1.4</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">00 00 00 30</span></td> <td style="line-height:25px"><span style="color:#003366; line-height:25px">48.0<br style="line-height:25px"></span></td> </tr> </tbody></table> <span style="line-height:25px">注1:</span><span style="color:#003366; line-height:25px">javac 有个 -target 参数,编译时可以通过</span><span style="color:#003366; line-height:25px"><span style="line-height:21px; font-family:verdana,sans-serif"><span style="line-height:22px">target</span></span><span style="line-height:21px; font-family:verdana,sans-serif">参数来设置编译时所使用的jdk版本。比如如果目标 JVM 是 1.3 的话,编译选项就可以用 -target 1.3 -source 1.3 了。</span></span> </div> <div style="line-height:25px"><span style="line-height:21px; font-family:verdana,sans-serif"><span style="line-height:21px"><span style="color:#003366; line-height:25px">相应的如果使用 ant ,<span style="line-height:25px; font-family:Arial,Helvetica,sans-serif; color:rgb(0,0,0)"><span style="line-height:21px; font-family:verdana,sans-serif"><span style="color:#003366; line-height:22px">编译时可以通过</span></span><span style="color:#003366; line-height:22px"><span style="line-height:21px; font-family:verdana,sans-serif"><span style="line-height:22px">target</span></span><span style="line-height:21px; font-family:verdana,sans-serif">参数来设置编译时所使用的jdk版本。比如:</span></span></span><br style="line-height:25px"> &lt;javac target="1.4" source="1.4" ............................/&gt;</span></span></span></div> <div style="line-height:25px"> <span style="line-height:21px; font-family:verdana,sans-serif"><span style="line-height:21px"><span style="line-height:25px">注2</span><span style="color:#003366; line-height:25px">:javac中</span></span></span><span style="color:#003366; line-height:25px"><span style="line-height:21px; font-family:verdana,sans-serif">source和</span><span style="line-height:21px; font-family:verdana,sans-serif">target 的意义</span></span> </div> <div style="line-height:25px"><span style="color:#FF6600; line-height:25px"><span style="line-height:21px; font-family:verdana,sans-serif"><span style="line-height:21px"></span></span><span style="line-height:21px; font-family:verdana,sans-serif">-source &lt;版本&gt; 提供与指定版本的源兼容性</span></span></div> <span style="line-height:21px; font-family:verdana,sans-serif"><span style="color:#FF6600; line-height:25px">-target &lt;版本&gt; 生成特定 VM 版本的类文件</span></span> <div style="line-height:25px"><span style="color:#993300; line-height:25px"><span style="line-height:21px; font-family:verdana,sans-serif">source才是真正的指明代码的兼容性,</span><span style="line-height:21px; font-family:verdana,sans-serif">target则是指定了生成class的格式的版本号,即</span><span style="line-height:21px; font-family:verdana,sans-serif">生成特定 VM 版本的类文件。</span></span></div> </wbr>
<think>我们正在寻找如何查看Java类文件的编译JDK版本信息的方法。根据引用[1]和引用[2],我们可以通过查看类文件中的主版本号(major version)来确定编译该类的JDK版本。引用[1]提供了不同Java版本对应的主版本号,而引用[2]则展示了一个Java程序,用于读取类文件并输出其主版本号和次版本号。 方法一:使用命令行工具(如Linux下的od命令) 步骤: 1. 使用od命令查看类文件的前几个字节(主要是第7和第8个字节,因为前4个字节是魔数CAFEBABE,接着两个字节是次版本号,再两个字节是主版本号)。 2. 定位到类文件的第7个字节(跳过前6个字节),然后读取两个字节(即第7和第8字节)作为主版本号。 示例命令: ```bash # 查看类文件的前16个字节(以十六进制显示) od -t x1 -j 0 -N 16 YourClass.class ``` 输出可能类似于: ``` 0000000 ca fe ba be 00 00 00 34 00 23 ... ``` 其中,第5-8个字节(每两个为一组)表示次版本号和主版本号(这里00 00是次版本号,00 34是主版本号,转换为十进制是52,对应Java 8)。 注意:由于版本号是大端存储,所以上面00 34就是主版本号,十六进制的0034转换为十进制是52。 方法二:使用Java程序读取类文件(如引用[2]所示) 我们可以编写一个简单的Java程序来读取类文件的主版本号和次版本号。 示例代码(修改自引用[2]): ```java import java.io.*; public class ClassVersionChecker { private static final int MAGIC = 0xCAFEBABE; public static void main(String[] args) { if (args.length != 1) { System.out.println("Usage: java ClassVersionChecker <class file>"); return; } try (DataInputStream dis = new DataInputStream(new FileInputStream(args[0]))) { int magic = dis.readInt(); if (magic != MAGIC) { System.out.println("Not a valid class file!"); return; } int minorVersion = dis.readUnsignedShort(); int majorVersion = dis.readUnsignedShort(); System.out.println("Class version: " + majorVersion + "." + minorVersion); System.out.println("Compiled with JDK: " + mapMajorVersionToJDK(majorVersion)); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static String mapMajorVersionToJDK(int majorVersion) { // 根据引用[1]的映射关系 if (majorVersion >= 46) { int jdkVersion = majorVersion - 44; // 例如52对应8(因为52-44=8) if (majorVersion >= 49) { // Java 5开始是49 // 从Java 5(49)开始,版本号与JDK版本的对应关系为:majorVersion - 44 return "Java " + (majorVersion - 44); } else { // 对于更早的版本,可以直接用映射表 // 这里我们根据引用[1]的映射关系 switch (majorVersion) { case 46: return "Java 1.2"; case 47: return "Java 1.3"; case 48: return "Java 1.4"; default: return "Unknown"; } } } else { return "Pre-Java 1.2"; } } } ``` 使用步骤: 1. 将上述代码保存为ClassVersionChecker.java。 2. 编译该程序:`javac ClassVersionChecker.java` 3. 运行程序并指定要检查的类文件:`java ClassVersionChecker YourClass.class` 方法三:使用javap工具(JDK自带) 实际上,JDK自带的javap工具也可以查看类文件的版本信息,但通常我们用它来查看字节码。不过,通过它的输出也可以间接得到版本号。 命令: ```bash javap -verbose YourClass | grep "major version" ``` 在输出中,我们可以看到类似这样的行: ``` major version: 52 ``` 然后根据引用[1]的映射关系,52对应Java 8。 注意:这个方法需要知道如何解析主版本号对应的JDK版本。 总结: 以上三种方法都可以查看类文件的编译JDK版本。其中,使用javap命令可能是最简便的,因为不需要额外的工具或编写程序。 下面我们提供主版本号与JDK版本的对应关系(部分): - 52: Java 8 - 51: Java 7 - 50: Java 6 - 49: Java 5 - 48: Java 1.4 - 47: Java 1.3 - 46: Java 1.2 更多的版本对应关系可参考引用[1]。 因此,用户可以根据需要选择其中一种方法。 相关问题: 1. 如何通过命令行快速查看类文件的编译版本? 2. 主版本号与JDK版本之间的对应关系是怎样的? 3. 如何在没有安装JDK的环境中查看类文件的编译版本? </think>### 查看 Java 类文件编译版本的方法 以下是三种常用的方法,可快速检测 `.class` 文件的编译 JDK 版本: --- #### 方法一:使用 `javap` 工具(推荐) ```bash javap -verbose YourClass.class | grep "major" ``` **输出示例**: ```bash major version: 52 # 对应 Java 8 major version: 61 # 对应 Java 17 ``` **原理**: 类文件头部的 `major version` 标识编译时使用的 JDK 主版本号[^1][^2]。 --- #### 方法二:十六进制查看器(无需 JDK) ```bash # Linux/Mac xxd -p -l 8 YourClass.class | head -c 16 # Windows PowerShell Format-Hex -Path YourClass.class -Count 8 ``` **输出解析**: ``` cafebabe 0000 0034 │ └─ 主版本号(十六进制) └─ 次版本号 ``` **版本对应**: - `0034` (十六进制) = 52 (十进制) → **Java 8** - `003d` (十六进制) = 61 (十进制) → **Java 17** (完整对照表见下文)[^1] --- #### 方法三:Java 程序解析(可编程实现) ```java import java.io.*; public class ClassVersionChecker { public static void main(String[] args) throws IOException { try (DataInputStream dis = new DataInputStream( new FileInputStream("YourClass.class"))) { int magic = dis.readInt(); if (magic != 0xCAFEBABE) { System.out.println("无效的类文件"); return; } int minor = dis.readUnsignedShort(); // 次版本号 int major = dis.readUnsignedShort(); // 主版本号 System.out.printf("编译版本: Java %d (主版本 %d)%n", major - 44, major); // 转换公式 } } } ``` **输出**: ``` 编译版本: Java 8 (主版本 52) ``` --- ### JDK 版本与主版本号对照表 | 主版本号 | JDK 版本 | 类文件标识 | |---------|----------|-----------| | 52 | Java 8 | `0x34` (0034) | | 53 | Java 9 | `0x35` (0035) | | 55 | Java 11 | `0x37` (0037) | | 61 | Java 17 | `0x3D` (003d) | | 62 | Java 18 | `0x3E` (003e) | > 计算公式: **JDK版本 = 主版本号 - 44**[^1] > (例如:61 - 44 = 17 ⇒ Java 17) --- ### 关键原理 1. **魔数标识**:所有合法类文件以 `0xCAFEBABE` 开头(4字节)[^2] 2. **版本结构**: ``` [0-3] 字节: CA FE BA BE (魔数) [4-5] 字节: 次版本号 (通常为00 00) [6-7] 字节: 主版本号 (关键标识) ``` 3. **版本映射**:Oracle 采用线性映射策略,主版本号 = JDK主版本 + 44[^1] > **提示**:生产环境建议使用 `javap` 命令,开发调试可用十六进制查看器快速验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值