使用 javap 命令(最常用、最推荐)
javap 是 JDK 自带的一个反汇编工具,专门用来解析 .class 文件并生成可读性较好的字节码信息,它是最常用、最标准的查看方式。

基本用法
你需要一个 .class 文件,如果你有一个 .java 源文件,可以先编译它:
# 编译 MyDemo.java 文件,生成 MyDemo.class javac MyDemo.java
使用 javap 命令来查看 MyDemo.class。
常用选项
javap 的强大之处在于它的各种选项。
a. 查看类的公共信息(默认)
不使用任何选项,javap 会显示类的版本、字段、方法等公共信息。

javap MyDemo.class
示例输出:
Compiled from "MyDemo.java"
public class MyDemo {
public MyDemo();
public static void main(java.lang.String[]);
}
这告诉你这是一个名为 MyDemo 的公共类,有一个公共的构造函数 public MyDemo() 和一个公共的静态主方法 public static void main(String[] args)。
b. 查看详细信息(-v 或 -verbose)
这是最常用的选项,它会显示非常详细的信息,包括常量池、访问标志、字段、方法、字节码指令等。
javap -v MyDemo.class
示例输出(部分):
Classfile /path/to/MyDemo.class
Last modified ...; size 455 bytes
MD5 checksum ...
Compiled from "MyDemo.java"
public class MyDemo
minor version: 0
major version: 52 // 对应 Java 8
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #6.#15 // java/lang/Object."<init>":()V
#2 = Fieldref #16.#17 // java/lang/System.out:Ljava/io/PrintStream;
... (常量池内容非常多)
{
public MyDemo();
descriptor: ()V
flags: 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 1: 0
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
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
}
这个输出非常有用:
- Constant pool: 常量池,是
.class文件的数据仓库。 - Code: 方法的字节码指令。
0: aload_0,1: invokespecial等就是 JVM 可以直接执行的指令。 - LineNumberTable: 将字节码指令与源代码行号对应起来,方便调试。
- descriptor: 方法的描述符,
([Ljava/lang/String;)V表示接受一个字符串数组参数,返回 void。
c. 查看常量池(-c)
-c 选项会先输出类的结构,然后紧接着输出每个方法的字节码指令。
javap -c MyDemo.class
示例输出(main方法的字节码部分):
public static void main(java.lang.String[]);
Code:
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
d. 查看内部结构和行号(-l)
-l 选项会显示行号表和局部变量表。
javap -l MyDemo.class
示例输出(main方法部分):
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
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
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 args [Ljava/lang/String;
LocalVariableTable 显示了方法中的局部变量,Slot 是变量在栈帧中的位置。
e. 查看所有成员(包括私有的)
默认情况下,javap 只显示 public 和 protected 成员。-p 或 -private 选项可以显示所有成员,包括 private 的。
javap -p MyDemo.class
f. 查看继承关系(-s)
-s 选项会输出内部类型签名。
javap -s MyDemo.class
使用图形化工具(更直观)
如果你不习惯命令行,或者想更直观地分析类的结构,可以使用图形化工具。
IntelliJ IDEA
IDEA 内置了强大的 .class 文件查看器。
- 在项目中找到
.class文件(通常在target或build目录下)。 - 右键点击
.class文件,选择 "Open" 或直接双击。 - IDEA 会在一个新标签页中打开该文件,显示其结构,包括:
- Overview: 类的基本信息(包名、父类、实现的接口)。
- Fields: 所有字段(成员变量)。
- Methods: 所有方法,点击方法可以查看其字节码、常量池引用和行号表。
Eclipse
Eclipse 也有类似的功能。
- 切换到 "Java" 透视图。
- 在包资源管理器中找到
.class文件。 - 右键点击,选择 "Open With" -> "Class File Editor"。
- 打开后,你可以看到类的层次结构、字段和方法的签名,并能导航到相关代码。
jclasslib
这是一个非常流行的、专门用于查看 .class 文件结构的插件,可以安装在 IDEA 和 Eclipse 中。
- 功能: 它提供了一个非常清晰、美观的界面来展示常量池、字段、方法、代码属性等所有
.class文件的内容。 - 安装: 在 IDEA/Eclipse 的插件市场中搜索 "jclasslib" 并安装。
- 使用: 安装后,右键点击
.class文件,选择 "Open in jclasslib Class File Viewer"。
使用专业字节码分析工具(更深入)
如果你需要进行性能分析、理解代码执行流程或进行逆向工程,可以使用更专业的工具。
Bytecode Viewer (BCV)
这是一个功能极其强大的开源字节码查看器和编辑器。
- 特点:
- 支持反编译为 Java、Kotlin、Scala 等多种语言。
- 支持字节码级别的编辑和重编译。
- 集成了多种反编译器(如 CFR, Procyon, Fernflower)。
- 图形化界面,操作直观。
- 适用场景: 逆向工程、代码混淆分析、恶意软件分析、深度字节码学习和修改。
CFR
CFR 是一个业界领先的反编译器,命令行工具,反编译质量非常高。
- 特点:
- 反编译生成的代码可读性好,能还原很多复杂的结构(如
try-catch-finally、switch等)。 - 支持最新的 Java 版本。
- 反编译生成的代码可读性好,能还原很多复杂的结构(如
- 使用示例:
# 将 MyDemo.class 反编译为 MyDemo.java 文件 cfr MyDemo.class
它会直接在控制台输出反编译后的 Java 代码,或者你可以使用
-o参数指定输出文件。
总结与对比
| 工具/方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
javap |
JDK自带,无需安装;功能全面,可精确查看字节码指令。 | 命令行,输出格式固定,不够直观。 | 日常开发、调试、学习JVM指令的首选。 |
| IDEA/Eclipse内置查看器 | 图形化界面,与开发环境无缝集成;方便查看行号、跳转到源码。 | 功能相对 javap 简单,无法像 javap -v 那样显示所有字节码细节。 |
快速了解类的结构、继承关系和成员。 |
| jclasslib插件 | 界面美观,专门为查看.class文件设计;常量池等信息展示清晰。 | 需要安装插件,功能专注于查看,不能编辑。 | 深入学习.class文件格式、常量池等。 |
| Bytecode Viewer (BCV) | 功能最强大,支持反编译、编辑、重编译;集成多种工具。 | 功能过于复杂,学习成本高;非轻量级工具。 | 逆向工程、代码混淆分析、深度字节码修改。 |
| CFR | 反编译质量顶尖,生成的代码可读性极高。 | 本质是反编译器,不直接展示原始字节码结构。 | 将.class文件还原成可读的Java源代码。 |
给你的建议:
- 如果你只是想快速看一下类的方法和结构:使用 IDEA/Eclipse 的内置查看器。
- 如果你想学习JVM,或者调试性能问题:熟练掌握
javap -v是必不可少的。 - 如果你想深入理解
.class文件的内部结构(如常量池):安装 jclasslib 插件。 - 如果你想把
.class文件变回.java文件:使用 CFR。
