如果我们看到.class文件结构,它会说: 偏移量0x04-0x05适用于JDK的次要版本,以及 偏移量0x06-0x07适用于JDK的主要版本
我使用eclipse进行Java项目开发,JDK1.5.0_7 / JRE配置为JRE系统库,类文件显示偏移量为0x00 0x00 0x00 0x31。
如何将编译器更改为JDK1.5.0_7,使偏移量变为0x00 0x07 0x00 0x31?
答案 0 :(得分:2)
您无法在编译期间自行指定次要编号。
主要和次要编号不表示用于编译的JDK版本。它们表示类文件格式的版本。看看这个SO answer。
类文件版本还指定了能够执行此类文件的JRE版本。例如:如果major.minor版本为0x30.0x00,则至少需要一个JRE 1.4才能执行此类文件。并非在所有情况下都意味着之前的JRE无法理解字节代码。一旦你使用了以前的Java版本中不存在的Java语言特性/运行时类,这就不再是真的了。
一个简单的例子
public class Scratch {
public static void main(String[] args) {
System.out.println("foobar");
}
}
这个简单的类可以使用与JDK的默认类文件版本不同的
进行编译以下将为1.4版本编译它
javac -source 1.4 -target 1.4 Scratch
在这个简单的例子中生成的字节码仍然是相同的。这个简单示例的最低可能类文件版本是2D.E(使用javac -target 1.1 -source 1.2 Scratch.java编译它)。然后JRE 1.1(用JRE 1.1.8验证)可以运行它。
要检查版本,您可以使用此代码段
import java.io.DataInputStream;
import java.io.FileInputStream;
public class ClassFileVersion {
// add exception handling, left out only for the example
public static void main(String[] args) throws Exception {
String filename = args[0];
try (DataInputStream in = new DataInputStream(new FileInputStream(filename))) {
int magic = in.readInt();
if (magic != 0xcafebabe) {
System.out.println(filename + " looks not like a Java class file.");
}
int minor = in.readUnsignedShort();
int major = in.readUnsignedShort();
System.out.printf("majaor.minor: %X.%X hex %d.%d dec%n", major, minor, major, minor);
}
}
}
修改强>
这是一个展示影响的小片段。
Scratch.java
运行Scratch.class
Path path = Paths.get("Scratch.class"); byte[] bytes = Files.readAllBytes(path); bytes[5] = 1; // it was zero before Files.write(path, bytes, StandardOpenOption.TRUNCATE_EXISTING)
运行更改的类文件java Scratch
执行将失败(错误消息的措辞可能会有所不同,具体取决于您使用的JRE)
java.lang.UnsupportedClassVersionError: Scratch has been compiled by a more recent version of the Java Runtime (class file version 52.1), this version of the Java Runtime only recognizes class file versions up to 52.0
如果编译较低主要版本的源(-target选项),则以前的JRE可以执行字节码(请参阅前面提到的限制)。
假设您使用JDK 8 javac -target 1.4 -source 1.4 Scratch.java
运行此命令。 javac
发生了不同的事情。首先,它检查Scratch.java
是否仅使用Java 1.4中提供的语言功能。其次,生成的Scratch.class
获得了一个在Java 1.4(30.0 hex)中使用的major.minor类文件版本。然后,您可以使用JRE 1.4作为java Scratch
运行此类。