如何使用eclipse在特定的次要版本的JDK上构建java文件?

时间:2015-11-20 06:19:43

标签: java eclipse

如果我们看到.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?

1 个答案:

答案 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);
        }
    }
}

修改

这是一个展示影响的小片段。

  1. 使用您当前的JDK编译上述Scratch.java
  2. 运行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)
  3. 运行更改的类文件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
  4. 如果编译较低主要版本的源(-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运行此类。