2008-08-25 24 views
103

Có ai trong số các bạn biết về một công cụ sẽ tìm kiếm các tệp .class và sau đó hiển thị các phiên bản đã biên dịch của chúng không?Công cụ để đọc và hiển thị các phiên bản Java .class

Tôi biết bạn có thể xem chúng riêng lẻ trong trình chỉnh sửa hex nhưng tôi có rất nhiều tệp lớp để xem lại (một thứ trong ứng dụng khổng lồ của tôi được biên dịch sang Java6 vì một số lý do).

+0

, tiện ích trùng lặp http://stackoverflow.com/questions/1096148/how-to-check-the -jdk-phiên bản-được sử dụng-để-biên dịch-a-class-file đã trả lời một số công cụ tiện dụng không được đề cập ở đây. – Vadzim

Trả lời

129

Sử dụng công cụ javap mà đi kèm với JDK. Tùy chọn -verbose sẽ in số phiên bản của tệp lớp.

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

Để chỉ hiển thị các phiên bản:

WINDOWS> javap -verbose MyClass | find "version" 
LINUX > javap -verbose MyClass | grep version 
39

Thật dễ dàng để đọc các số class file signature và nhận các giá trị này mà không có API của bên thứ ba. Tất cả những gì bạn cần làm là đọc 8 byte đầu tiên.

ClassFile { 
    u4 magic; 
    u2 minor_version; 
    u2 major_version; 

Đối với file class phiên bản 51,0 (Java 7), các byte mở là:

CA FE BA BE 00 00 00 33 

... nơi 0xCAFEBABE là byte ma thuật, 0x0000 là phiên bản nhỏ và 0x0033 là phiên bản lớn .

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

thư mục Walking (File) và tài liệu lưu trữ (JarFile) tìm kiếm các file class là tầm thường.

Joe Darcy's blog danh sách của Oracle các class version to JDK version mappings lên đến 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 
+0

Cũng nên nhớ rằng khẳng định chỉ chạy nếu nó được kích hoạt khi khởi chạy java để bạn có thể đọc các tập tin rác nếu bạn không sử dụng IllegalArgumentException (ví dụ) – jontejj

9

Nếu bạn đang ở trên một hệ thống unix bạn chỉ có thể làm một

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

(phiên bản của tôi về tập tin nói "biên soạn lớp dữ liệu

Java , phiên bản 50.0 "cho các lớp java6).

+0

Trên macOS (10.12.6 ít nhất), đầu ra còn hữu ích hơn: file '* .class' sản xuất: 'ClassName.class: dữ liệu biên soạn lớp Java, phiên bản 50.0 (Java 1.6)' – Gary

17

Trên Unix-like

file /path/to/Thing.class

sẽ cung cấp cho các loại tập tin và phiên bản là tốt. Đây là những gì đầu ra trông giống như:

dữ liệu lớp Java được biên dịch, phiên bản 49,0

+0

(giản thể từ câu trả lời của WMR) – phunehehe

+0

đây là cách đơn giản hơn so với các giải pháp khác – mmuller

5

Tuy nhiên, một phiên bản java séc

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

Trong nhật thực nếu bạn không có nguồn kèm theo. Hãy nhớ dòng đầu tiên sau nút đính kèm nguồn.

// Biên soạn từ CDestinoLog.java (phiên bản 1.5: 49,0, siêu chút)

enter image description here

2

Có lẽ điều này giúp ai đó, quá. Có vẻ là cách dễ dàng hơn để có được phiên bản JAVA được sử dụng để biên dịch/xây dựng .class.Bằng cách này rất hữu ích cho ứng dụng/lớp tự kiểm tra trên phiên bản JAVA.

Tôi đã trải qua thư viện JDK và tìm thấy hằng số hữu ích này: com.sun.deploy.config.BuiltInProperties.CURRENT_VERSION. Tôi không biết kể từ khi nó được trong JDK JAVA.

Cố đoạn mã này trong vài hằng số phiên bản tôi nhận được kết quả dưới đây:

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()); 

đầu ra:

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 

Trong lớp bytecode có thực sự là hằng số được lưu trữ - xem phần được đánh dấu màu đỏ của Main.call - constant stored in .class bytecode

liên tục là trong lớp học sử dụng để kiểm tra nếu JAVA phiên bản đã cũ (xem How Java checks that is out of date) ...

Các vấn đề liên quan