代码之家  ›  专栏  ›  技术社区  ›  SCdF

读取和显示Java.class版本的工具

  •  111
  • SCdF  · 技术社区  · 16 年前

    你们中有人知道一个工具可以搜索.class文件,然后显示它们的编译版本吗?

    我知道您可以在十六进制编辑器中单独查看它们,但是我有很多类文件要查看(我的大型应用程序中的一些东西出于某种原因正在编译为Java6)。

    7 回复  |  直到 7 年前
        1
  •  138
  •   Community CDub    12 年前

    使用 javap JDK附带的工具。这个 -verbose 选项将打印类文件的版本号。

    > javap -verbose MyClass
    Compiled from "MyClass.java"
    public class MyClass
      SourceFile: "MyClass.java"
      minor version: 0
      major version: 46
    ...
    

    仅显示版本:

    WINDOWS> javap -verbose MyClass | find "version"
    LINUX  > javap -verbose MyClass | grep version
    
        2
  •  43
  •   Vadzim    7 年前

    很容易读懂 class file signature 在没有第三方API的情况下获取这些值。您所需要做的就是读取前8个字节。

    ClassFile {
        u4 magic;
        u2 minor_version;
        u2 major_version;
    

    对于类文件版本51(Java 7),打开字节为:

    CA FE BA BE 00 00 00 33
    

    …其中,0xcafebabe是魔力字节,0x0000是次要版本,0x0033是主要版本。

    import java.io.*;
    
    public class Demo {
      public static void main(String[] args) throws IOException {
        ClassLoader loader = Demo.class.getClassLoader();
        try (InputStream in = loader.getResourceAsStream("Demo.class");
            DataInputStream data = new DataInputStream(in)) {
          if (0xCAFEBABE != data.readInt()) {
            throw new IOException("invalid header");
          }
          int minor = data.readUnsignedShort();
          int major = data.readUnsignedShort();
          System.out.println(major + "." + minor);
        }
      }
    }
    

    正在浏览目录( File )和档案( JarFile )查找类文件是很简单的。

    甲骨文公司 Joe Darcy's blog 列出 class version to JDK version mappings 到Java 7:

    Target   Major.minor Hex
    1.1      45.3        0x2D
    1.2      46.0        0x2E
    1.3      47.0        0x2F
    1.4      48.0        0x30
    5 (1.5)  49.0        0x31
    6 (1.6)  50.0        0x32
    7 (1.7)  51.0        0x33
    8 (1.8)  52.0        0x34
    9        53.0        0x35
    
        3
  •  21
  •   phunehehe    13 年前

    在类UNIX上

    file /path/to/Thing.class

    将提供文件类型和版本。输出如下:

    编译Java类数据,版本49

        4
  •  9
  •   WMR    16 年前

    如果你在一个Unix系统上,你可以做一个

    find /target-folder -name \*.class | xargs file | grep "version 50\.0"
    

    (我的版本的文件称为Java6类的“编译Java类数据,版本50”)。

        5
  •  5
  •   igo    10 年前

    又一个Java版本检查

    od -t d -j 7 -N 1 ApplicationContextProvider.class | head -1 | awk '{print "Java", $2 - 44}'
    
        6
  •  4
  •   PbxMan    9 年前

    在Eclipse中,如果没有附加源。注意“附加源”按钮后的第一行。

    //从cdestinolog.java编译( 版本1.5:49.0,超级位 )

    enter image description here

        7
  •  2
  •   Community CDub    7 年前

    也许这对某些人也有帮助。看起来有更简单的方法让Java版本用于编译/构建.class。这种方式对Java版本的应用程序/类自检非常有用。

    我浏览了JDK库,发现了这个有用的常量: com.sun.deploy.config.builtinproperties.current_版本 . 我不知道从什么时候起它就在JAVA JDK中。

    尝试将这段代码用于多个版本常量,结果如下:

    SRC:

    System.out.println("JAVA DEV       ver.: " + com.sun.deploy.config.BuiltInProperties.CURRENT_VERSION);
    System.out.println("JAVA RUN     v. X.Y: " + System.getProperty("java.specification.version") );
    System.out.println("JAVA RUN v. W.X.Y.Z: " + com.sun.deploy.config.Config.getJavaVersion() ); //_javaVersionProperty
    System.out.println("JAVA RUN  full ver.: " + System.getProperty("java.runtime.version")  + " (may return unknown)" );
    System.out.println("JAVA RUN       type: " + com.sun.deploy.config.Config.getJavaRuntimeNameProperty() );
    

    输出:

    JAVA DEV       ver.: 1.8.0_77
    JAVA RUN     v. X.Y: 1.8
    JAVA RUN v. W.X.Y.Z: 1.8.0_91
    JAVA RUN  full ver.: 1.8.0_91-b14 (may return unknown)
    JAVA RUN       type: Java(TM) SE Runtime Environment
    

    在类字节码中,确实存在存储常量-请参见main.call中红色标记的部分- constant stored in .class bytecode

    常数在类中用于检查Java版本是否过期(参见 How Java checks that is out of date )

    推荐文章