如何查看编译过的.Class文件

使用javap工具使用命令行窗口

Class文件是经过JDK中javac工具编译后的一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符. 如何查看编译后的Class文件?推荐两种不需要安装任何额外工具的查看方式.在IDE中打开.class文件,会被内置的反编译插件反编译,还原成java类文件,既不能起到查看.class文件的目的,也不符合不安装额外工具的要求.

使用javap工具

对于任意的类,首先使用javac工具进行编译

javac HelloWorld.java

使用JDK中的javap工具打开.class文件

javap -verbose HelloWorld.class

即可得到相应的.class文件内容

Classfile /E:/学习及反思/HelloWorld.class

Last modified 2019-1-8; size 426 bytes

MD5 checksum dfd16ec7464dcda9bfc32d22988a5a82

Compiled from "HelloWorld.java"

public class HelloWorld

SourceFile: "HelloWorld.java"

minor version: 0

major version: 51

flags: ACC_PUBLIC, ACC_SUPER

Constant pool:

#1 = Methodref #6.#15 // java/lang/Object."":()V

#2 = Fieldref #16.#17 // java/lang/System.out:Ljava/io/PrintStream;

#3 = String #18 // Hello World!

#4 = Methodref #19.#20 // java/io/PrintStream.println:(Ljava/lang/String;)V

#5 = Class #21 // HelloWorld

#6 = Class #22 // java/lang/Object

#7 = Utf8

#8 = Utf8 ()V

#9 = Utf8 Code

#10 = Utf8 LineNumberTable

#11 = Utf8 main

#12 = Utf8 ([Ljava/lang/String;)V

#13 = Utf8 SourceFile

#14 = Utf8 HelloWorld.java

#15 = NameAndType #7:#8 // "":()V

#16 = Class #23 // java/lang/System

#17 = NameAndType #24:#25 // out:Ljava/io/PrintStream;

#18 = Utf8 Hello World!

#19 = Class #26 // java/io/PrintStream

#20 = NameAndType #27:#28 // println:(Ljava/lang/String;)V

#21 = Utf8 HelloWorld

#22 = Utf8 java/lang/Object

#23 = Utf8 java/lang/System

#24 = Utf8 out

#25 = Utf8 Ljava/io/PrintStream;

#26 = Utf8 java/io/PrintStream

#27 = Utf8 println

#28 = Utf8 (Ljava/lang/String;)V

{

public HelloWorld();

flags: ACC_PUBLIC

Code:

stack=1, locals=1, args_size=1

0: aload_0

1: invokespecial #1 // Method java/lang/Object."":()V

4: return

LineNumberTable:

line 1: 0

public static void main(java.lang.String[]);

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=2, locals=1, args_size=1

0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;

3: ldc #3 // String Hello World!

5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

8: return

LineNumberTable:

line 3: 0

line 4: 8

}

使用命令行窗口

首先编译任意.java类文件

javac HelloWorld.java

使用命令行窗口查看.class文件,这时打开的文件为2进制显示

vim HelloWorld.class

一坨乱码 like a shit!

Êþ º ¾ ^@^@^@3^@^]

^@^F^@^O ^@^P^@^Q^H^@^R

^@^S^@^T^G^@^U^G^@^V^A^@^F^A^@^C()V^A^@^DCode^A^@^OLineNumberTable^A^@^Dmain^A^@^V([Ljava/lang/String;)V^A^@

SourceFile^A^@^OHelloWorld.java^L^@^G^@^H^G^@^W^L^@^X^@^Y^A^@^LHello World!^G^@^Z^L^@^[^@^\^A^@

HelloWorld^A^@^Pjava/lang/Object^A^@^Pjava/lang/System^A^@^Cout^A^@^ULjava/io/PrintStream;^A^@^Sjava/io/PrintStream^A^@^Gprintln^A^@^U(Ljava/lang/String;)V^@!^@^E^@^F^@^@^@^@^@^B^@^A^@^G^@^H^@^A^@ ^@^@^@^]^@^A^@^A^@^@^@^E*·^@^A±^@^@^@^A^@

^@^@^@^F^@^A^@^@^@^A^@ ^@^K^@^L^@^A^@ ^@^@^@%^@^B^@^A^@^@^@ ² ^@^B^R^C¶ ^@^D±^@^@^@^A^@

^@^@^@

^@^B^@^@^@^C^@^H^@^D^@^A^@^M^@^@^@^B^@^N

使用命令:%!xxd,即可转变为16进制显示

截取部分

00000000: cafe babe 0000 0033 001d 0a00 0600 0f09 .......3........

00000010: 0010 0011 0800 120a 0013 0014 0700 1507 ................

00000020: 0016 0100 063c 696e 6974 3e01 0003 2829 ........()

00000030: 5601 0004 436f 6465 0100 0f4c 696e 654e V...Code...LineN

00000040: 756d 6265 7254 6162 6c65 0100 046d 6169 umberTable...mai

00000050: 6e01 0016 285b 4c6a 6176 612f 6c61 6e67 n...([Ljava/lang

00000060: 2f53 7472 696e 673b 2956 0100 0a53 6f75 /String;)V...Sou

00000070: 7263 6546 696c 6501 000f 4865 6c6c 6f57 rceFile...HelloW

00000080: 6f72 6c64 2e6a 6176 610c 0007 0008 0700 orld.java.......

00000090: 170c 0018 0019 0100 0c48 656c 6c6f 2057 .........Hello W

000000a0: 6f72 6c64 2107 001a 0c00 1b00 1c01 000a orld!...........

000000b0: 4865 6c6c 6f57 6f72 6c64 0100 106a 6176 HelloWorld...jav

000000c0: 612f 6c61 6e67 2f4f 626a 6563 7401 0010 a/lang/Object...

000000d0: 6a61 7661 2f6c 616e 672f 5379 7374 656d java/lang/System

000000e0: 0100 036f 7574 0100 154c 6a61 7661 2f69 ...out...Ljava/i

000000f0: 6f2f 5072 696e 7453 7472 6561 6d3b 0100 o/PrintStream;..

00000100: 136a 6176 612f 696f 2f50 7269 6e74 5374 .java/io/PrintSt

00000110: 7265 616d 0100 0770 7269 6e74 6c6e 0100 ream...println..

00000120: 1528 4c6a 6176 612f 6c61 6e67 2f53 7472 .(Ljava/lang/Str

00000130: 696e 673b 2956 0021 0005 0006 0000 0000 ing;)V.!........

00000140: 0002 0001 0007 0008 0001 0009 0000 001d ................

00000150: 0001 0001 0000 0005 2ab7 0001 b100 0000 ........*.......

00000160: 0100 0a00 0000 0600 0100 0000 0100 0900 ................

00000170: 0b00 0c00 0100 0900 0000 2500 0200 0100 ..........%.....

00000180: 0000 09b2 0002 1203 b600 04b1 0000 0001 ................

00000190: 000a 0000 000a 0002 0000 0003 0008 0004 ................

每个Class文件的头四个字节称为魔数(Magic Number),它的唯一作用是确定这个文件是否为一个能被虚拟机接收的Class文件.而java的Class文件的魔数是非常有情怀的,值为0xCAFEBABE,也就是java的标志.

文章参考: javap——查看class文件的方法 以16进制的形式查看java class二进制文件


适合 Ubuntu的8款最佳录屏软件
万达电影兑换券使用方法