1. 概述

在这个教程中,我们将探讨如何查找*.class*文件的Java发行版本,并查看如何检查jar文件中的Java版本。

2. Java中的*.class*版本

当Java源文件被编译时,会生成一个*.class文件。在某些情况下,我们需要找出编译后的类文件对应的Java发行版本。**每个Java主要版本都会为其生成的.class文件分配一个主要版本号。*

以下表格将*.class*的主要版本号映射到引入该类版本的JDK版本,并显示该版本号的十六进制表示:

Java发行版

类主要版本

十六进制

Java SE 18

62

003e

Java SE 17

61

003d

Java SE 16

60

003c

Java SE 15

59

003b

Java SE 14

58

003a

Java SE 13

57

0039

Java SE 12

56

0038

Java SE 11

55

0037

Java SE 10

54

0036

Java SE 9

53

0035

Java SE 8

52

0034

Java SE 7

51

0033

Java SE 6

50

0032

Java SE 5

49

0031

JDK 1.4

48

0030

JDK 1.3

47

002f

JDK 1.2

46

002e

JDK 1.1

45

002d

3. 对于*.class*的javap命令

让我们创建一个简单的类并使用JDK 8进行构建:

public class Sample {
    public static void main(String[] args) {
        System.out.println("Baeldung tutorials");
    }
}

为了确定类文件的版本,我们可以使用Java类文件反汇编器javap

javap命令的语法如下:

javap [option] [classname]

让我们以Sample.class为例来检查版本:

javap -verbose Sample

//stripped output ..
..
..
Compiled from "Sample.java"
public class test.Sample
  minor version: 0
  major version: 52
..
..

javap命令的输出所示,主要版本为52,这表明它是JDK8的。

虽然javap提供了许多详细信息,但我们只关心主要版本。

对于基于Linux的系统,我们可以使用以下命令仅获取主要版本:

javap -verbose Sample | grep major

类似地,对于Windows系统,我们可以使用的命令如下:

javap -verbose Sample | findstr major

在我们的示例中,这将给出主要版本52。

重要的是要注意,这个版本值并不表示应用程序是用相应的JDK构建的。类文件版本可能与编译时使用的JDK不同。

例如,如果我们使用JDK11构建代码,它应该产生一个版本为55的.class*文件。但如果我们在编译时使用了-target 8选项,那么.class文件的版本将是52。*

4. 使用hexdump检查*.class*版本

也可以使用任何十六进制编辑器来检查版本。Java类文件遵循规范。让我们看看其结构:

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    // other details
}

在这里,u1u2u4分别代表无符号的一个、两个和四个字节的整数。u4是一个标识类文件格式的魔数,其值为0xCAFEBABE,而u2是主要版本。

对于基于Linux的系统,我们可以使用hexdump工具解析任何.class文件:

> hexdump -v Sample.class
0000000 ca fe ba be 00 00 00 34 00 22 07 00 02 01 00 0b
0000010 74 65 73 74 2f 53 61 6d 70 6c 65 07 00 04 01 00
...truncated

在这个例子中,我们使用JDK8进行了编译。第一行的7和8索引提供了类文件的主要版本。因此,0034是其十六进制表示,对应的发行版本(根据我们之前看到的映射表)是JDK8。

作为一种替代方法,我们可以直接使用hexdump获取主要发布版本的十进制形式:

> hexdump -s 7 -n 1 -e '"%d"' Sample.class
52

这里,输出的52就是对应JDK8的类版本。

5. jar文件的版本

Java生态系统的jar文件包含一组捆绑在一起的类文件。为了了解jar文件是构建还是编译时使用的Java版本,我们可以提取jar文件,然后使用javaphexdump来检查*.class*文件的版本。

jar文件中还有一个名为MANIFEST.MF的文件,其中包含关于使用的JDK的一些头部信息。

例如,Build-JdkCreated-By头根据jar的构建方式存储JDK值:

Build-Jdk: 17.0.4

或者

Created-By: 17.0.4

6. 总结

在这篇文章中,我们学习了如何查找*.class*文件的Java版本。我们了解了javaphexdump命令以及它们在查找版本时的用法。此外,我们还了解了如何在jar文件中检查Java版本。