用于找出编译类文件的JDK版本的Java API?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1293308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 07:52:39  来源:igfitidea点击:

Java API to find out the JDK version a class file is compiled for?

versionjava

提问by Prabhu R

Are there any Java APIs to find out the JDK version a class file is compiled for? Of course there is the javap tool to find out the major version as mentioned in here. However I want to do it programmatically so that that I could warn the user to compile it for the appropriate JDK

是否有任何 Java API 可以找出编译类文件的 JDK 版本?当然有 javap 工具来找出这里提到的主要版本。但是我想以编程方式进行,以便我可以警告用户为适当的 JDK 编译它

采纳答案by RealHowTo

import java.io.*;

public class ClassVersionChecker {
    public static void main(String[] args) throws IOException {
        for (int i = 0; i < args.length; i++)
            checkClassVersion(args[i]);
    }

    private static void checkClassVersion(String filename)
        throws IOException
    {
        DataInputStream in = new DataInputStream
            (new FileInputStream(filename));

        int magic = in.readInt();
        if(magic != 0xcafebabe) {
            System.out.println(filename + " is not a valid class!");;
        }
        int minor = in.readUnsignedShort();
        int major = in.readUnsignedShort();
        System.out.println(filename + ": " + major + " . " + minor);
        in.close();
    }
}

The possible values are :

可能的值为:

major  minor Java platform version 
45       3           1.0
45       3           1.1
46       0           1.2
47       0           1.3
48       0           1.4
49       0           5
50       0           6
51       0           7
52       0           8
53       0           9
54       0           10
55       0           11
56       0           12
57       0           13
58       0           14

回答by Robert Munteanu

JavaP does have an API, but it's specific to the Sun JDK.

JavaP 确实有一个API,但它特定于 Sun JDK。

It's found in tools.jar, under sun/tools/javap/Main.class.

它位于tools.jar、 下sun/tools/javap/Main.class

回答by Michael Borgwardt

This gets you the contents of the class file:

这会让您获得类文件的内容:

MysteryClass.class.getResourceAsStream("MysteryClass.class")

MysteryClass.class.getResourceAsStream("MysteryClass.class")

Then look at bytes 5-8 to get the minor and major version. A mapping between those numbers and the JDK releases can be found here.

然后查看字节 5-8 以获取次要和主要版本。可以在此处找到这些数字与 JDK 版本之间的映射。

回答by basszero

Just read the class file directly. It's VERY easy to figure out the version. Check out the the specand wikiand then try the code. Wrapping this code and making is more useful/pretty is left as an exercise. Alternatively, you could use a library like BCEL, ASM, or JavaAssist

直接读取类文件即可。很容易找出版本。查看规范维基,然后尝试代码。包装此代码并制作更有用/漂亮作为练习。或者,您可以使用像BCELASMJavaAssist这样的库

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class ClassVersionTest
{
    private static final int JAVA_CLASS_MAGIC = 0xCAFEBABE;

    public static void main(String[] args)
    {
        try
        {
            DataInputStream dis = new DataInputStream(new FileInputStream("Test.class"));
            int magic = dis.readInt();
            if(magic == JAVA_CLASS_MAGIC)
            {
                int minorVersion = dis.readUnsignedShort();
                int majorVersion = dis.readUnsignedShort();

                /**
                 * majorVersion is ...
                 * J2SE 6.0 = 50 (0x32 hex),
                 * J2SE 5.0 = 49 (0x31 hex),
                 * JDK 1.4 = 48 (0x30 hex),
                 * JDK 1.3 = 47 (0x2F hex),
                 * JDK 1.2 = 46 (0x2E hex),
                 * JDK 1.1 = 45 (0x2D hex).
                 */

                System.out.println("ClassVersionTest.main() " + majorVersion + "." + minorVersion);
            }
            else
            {
                // not a class file
            }
        }
        catch (FileNotFoundException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

回答by McDowell

As others have shown, it is easy enough to do by reading the first eight bytes of a class file. If you want a pre-built binary library, you can download one here.

正如其他人所展示的,通过读取类文件的前八个字节很容易做到。如果你想要一个预先构建的二进制库,你可以在这里下载一个。

回答by skaffman

Apache BCELprovides this API:

Apache BCEL提供了这个 API:

JavaClass c = Repository.lookupClass("com.x.MyClass")
c.getMinor();
c.getMajor();

回答by rickumali

basszero's approach can be done via the UNIX command line, and the "od(1)" command:

basszero 的方法可以通过 UNIX 命令行和“od(1)”命令完成:

% od -x HelloWorldJava.class |head -2
0000000 feca beba 0000 3100 dc00 0007 0102 2a00
0000020 6f63 2f6d 6e65 6564 6163 642f 6d65 2f6f

"feca beba" is the magic number. The "0000 3100" is 0x31, which represents J2SE 5.0.

“feca beba”是神奇的数字。“0000 3100”是 0x31,代表 J2SE 5.0。

回答by Daniel Wille

On Linux, you can use the filecommand on a class file, which I found easiest for my use case. For example:

在 Linux 上,您可以file在类文件上使用该命令,我发现这对我的用例来说是最简单的。例如:

$ file Foo.class
Foo.class: compiled Java class data, version 50.0 (Java 1.6)