使用 UE 打开 class 文件,第一行内容:
00000000h: CA FE BA BE 00 00 00 32 00 A9 07 00 02 01 00 37 ; 漱壕...2.?....7
前四个字节为固定的 CA FE BA BE ,接下来的四个字节为次版本号(0000)和主版本号(0032)。
33:JDK1.7
32:JDK1.6
31:JDK1.5
30:JDK1.4
2F:JDK1.3
2E: JDK1.2
2D: JDK1.1
java的class文件的头8个字节为:"magic"+"minor_version"+"major_version",即分别为文件类型(魔数)、文件格式次版本号、主版本号,这8个字节以16进制表示,每两位构成一个字节:
(1) magic: class文件的前4个字节为它的魔数(magic number):0xCAFEBABE。魔数的作用在于辨别是否为class文件(class文件必然是以0xCAFEBABE开头的);
(2) minor_verxion和major_version: class文件的下面4个字节便是次、主版本号。java虚拟机在读取class文件时会判断它的主次版本号,当其版本号超过它能处理的范围时,java虚拟机将不会处理该class文件,例如低版本的虚拟机无法执行高版本虚拟机编译的class文件。
//一段小代码
import java.io.FileInputStream;
public class JavaVersionUtil {
private static final String str = "C:/Users/Administrator/Desktop/DBUtil.class";
// 版本号对应:
// 5.0
// 版本号(version):49.0
// 6.0
// 版本号(version):50.0
// 1.4
// 版本号(version):46.0
// 1.3
// 版本号(version):45.3
public static void main(String args[]) {
try {
// 读取文件数据,文件是当前目录下的First.class
FileInputStream fis = new FileInputStream(str);
int length = fis.available();
// 文件数据
byte[] data = new byte[length];
// 读取文件到字节数组
fis.read(data);
// 关闭文件
fis.close();
// 解析文件数据
parseFile(data);
} catch (Exception e) {
System.out.println(e);
}
}
private static void parseFile(byte[] data) {
// 输出魔数
System.out.print("魔数(magic):0x");
System.out.print(Integer.toHexString(data[0]).substring(6)
.toUpperCase());
System.out.print(Integer.toHexString(data[1]).substring(6)
.toUpperCase());
System.out.print(Integer.toHexString(data[2]).substring(6)
.toUpperCase());
System.out.println(Integer.toHexString(data[3]).substring(6)
.toUpperCase());
// 主版本号和次版本号码
int minor_version = (((int) data[4]) << 8) + data[5];
int major_version = (((int) data[6]) << 8) + data[7];
System.out.println("版本号(version):" + major_version + "."
+ minor_version);
}
}
JDK 编译器版本 | target 参数 | 十六进制 minor.major | 十进制 minor.major |
jdk1.1.8 | 不能带 target 参数 | 00 03 00 2D | 45.3 |
jdk1.2.2 | 不带(默认为 -target 1.1) | 00 03 00 2D | 45.3 |
jdk1.2.2 | -target 1.2 | 00 00 00 2E | 46.0 |
jdk1.3.1_19 | 不带(默认为 -target 1.1) | 00 03 00 2D | 45.3 |
jdk1.3.1_19 | -target 1.3 | 00 00 00 2F | 47.0 |
j2sdk1.4.2_10 | 不带(默认为 -target 1.2) | 00 00 00 2E | 46.0 |
j2sdk1.4.2_10 | -target 1.4 | 00 00 00 30 | 48.0 |
jdk1.5.0_11 | 不带(默认为 -target 1.5) | 00 00 00 31 | 49.0 |
jdk1.5.0_11 | -target 1.4 -source 1.4 | 00 00 00 30 | 48.0 |
jdk1.6.0_01 | 不带(默认为 -target 1.6) | 00 00 00 32 | 50.0 |
jdk1.6.0_01 | -target 1.5 | 00 00 00 31 | 49.0 |
jdk1.6.0_01 | -target 1.4 -source 1.4 | 00 00 00 30 | 48.0 |
jdk1.7.0 | 不带(默认为 -target 1.6) | 00 00 00 32 | 50.0 |
jdk1.7.0 | -target 1.7 | 00 00 00 33 | 51.0 |
jdk1.7.0 | -target 1.4 -source 1.4 | 00 00 00 30 | 48.0 |
Apache Harmony 5.0M3 | 不带(默认为 -target 1.2) | 00 00 00 2E | 46.0 |
Apache Harmony 5.0M3 | -target 1.4 | 00 00 00 30 | 48.0 |
转载于:https://blog.51cto.com/baser/1305974