Java源文件反编译成汇编语言:1.javac将Java源文件编译为.class文件,2.javap将.class文件反编译成汇编语言;.class文件结构
·
Java源文件反编译成汇编语言:1.javac编译Java源文件为.class文件,2.javap反编译.class文件成汇编语言;.class文件结构
Java源文件反编译成汇编语言
1.javac将Java源文件编译为.class文件
示例:
public class MyClass {
public static final int MAX_SIZE = 100;
public static final String HELLO = "Hello, World!";
}
在 .class 文件中的静态常量池会包含:
- 整数常量
100,对应MAX_SIZE。 - 字符串常量
"Hello, World!",对应HELLO。
打开存放该Java源文件的目录,进入dos窗口,执行命令,在当前目录生成对应的 .class 文件
javac .\文件名

使用notepad查看编译后的.class文件,需要安装进制转换插件

安装之后会重启notepad,重启完成选中进制转换

可以看到字节码文件格式化后是以16进制展示的,它的本质是二进制文件,里面存放的是16进制的字节元,以16进制展示的。
2.javap将.class文件反编译成汇编语言
.class文件本质是二进制文件,看起来很难受,因此Java提供了反编译技术,可以将对应的.class文件反编译成汇编语言,方便我们阅读。
在当前字节码文件目录执行命,将对应的.class文件反编译成汇编语言,并输出为.txt文件:
javap -p -v .\MyClass.class >MyClass.txt
命令参数解释:
-p:选项告诉 javap 显示类的所有成员,包括私有(private)、受保护(protected)、包级(default)和公共(public)成员。默认情况下,javap 只显示公共成员,通过使用-p选项,可以查看所有成员,无论它们的访问修饰符是什么。- 使用示例:
这将列出 MyClass 类的所有成员,包括 private、protected、default 和 public 字段及方法。javap -p MyClass
- 使用示例:
-v:选项告诉 javap 显示详细的字节码信息。这包括常量池、字段的签名、方法的字节码、局部变量表等详细信息。它通常用于深入分析类文件的结构和字节码指令。- 使用示例:
这将输出 MyClass 类的详细信息,包括类的字节码、常量池内容、字段、方法、签名、方法的字节码指令等。
- 使用示例:
- 组合使用:当 -p 和 -v 一起使用时,命令将显示类的所有成员(包括私有成员)以及详细的字节码信息。这个组合命令通常用于对类进行深入分析,查看其完整的结构和编译后的指令。
- 使用示例:
javap -p -v MyClass - 输出结果将包括:
- 类的所有字段(包括私有字段)
- 类的所有方法(包括私有方法)
- 常量池信息
- 字节码指令
- 局部变量表
- 其他编译相关的信息
- 使用示例:

.txt文件内容如下:
Classfile /D:/IdeaProjects/SutureMonster/sm-demo/src/main/java/com/sm/demo/Test/MyClass.class
Last modified 2024年12月16日; size 321 bytes
SHA-256 checksum cb02fe5b46f39d36c5ea75b334426df02c51e075ef95b2883de59c7b2de60779
Compiled from "MyClass.java"
public class com.sm.demo.Test.MyClass
minor version: 0
major version: 65
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #7 // com/sm/demo/Test/MyClass
super_class: #2 // java/lang/Object
interfaces: 0, fields: 2, methods: 1, attributes: 1
Constant pool:
#1 = Methodref #2.#3 // java/lang/Object."<init>":()V
#2 = Class #4 // java/lang/Object
#3 = NameAndType #5:#6 // "<init>":()V
#4 = Utf8 java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Class #8 // com/sm/demo/Test/MyClass
#8 = Utf8 com/sm/demo/Test/MyClass
#9 = Utf8 MAX_SIZE
#10 = Utf8 I
#11 = Utf8 ConstantValue
#12 = Integer 100
#13 = Utf8 HELLO
#14 = Utf8 Ljava/lang/String;
#15 = String #16 // Hello, World!
#16 = Utf8 Hello, World!
#17 = Utf8 Code
#18 = Utf8 LineNumberTable
#19 = Utf8 SourceFile
#20 = Utf8 MyClass.java
{
public static final int MAX_SIZE;
descriptor: I
flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
ConstantValue: int 100
public static final java.lang.String HELLO;
descriptor: Ljava/lang/String;
flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
ConstantValue: String Hello, World!
public com.sm.demo.Test.MyClass();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
}
SourceFile: "MyClass.java"
.class文件结构
ClassFile {
u4 magic;//字节码文件的规范,一般value是以0xCAFEBABE开头,俗称为魔术开头
u2 minor_version;//最小版本号
u2 major_version;//最大版本号
u2 constant_pool_count;//常量池数量
cp_info constant_pool[constant_pool_count-1];//常量池,这里指的是静态常量池
u2 access_flags;//访问标记
u2 this_class;//当前类
u2 super_class;//超类
u2 interfaces_count;//接口数量
u2 interfaces[interfaces_count];
u2 fields_count;//字段数量
field_info fields[fields_count];
u2 methods_count;//方法数量
method_info methods[methods_count];
u2 attributes_count;//属性数量
attribute_info attributes[attributes_count];
}
u2,u4,u8是无符号数据类型,是2的n次方。
注意:class文件结构里的常量池是指静态常量池
常量池一般分为三类,静态常量池,运行时常量池,字符串常量池。而class文件结构这里说的常量池指的是静态常量池。
静态常量池当中存放两个东西:
- 字面量:文本;字符串;final修饰的(final修饰的不一定都为常量)
- 符号引用:类、接口、字段、方法的一些描述信息
constant_pool是一个结构表,表示在结构及其子结构中引用的各种字符串常量、类和接口名称、字段名称和其他常量。每个表项的格式由其第一个“标记”字节表示。
更多推荐
所有评论(0)