我的编程空间,编程开发者的网络收藏夹
学习永远不晚

【Java可执行命令】(四)反编译工具javap:深入解析应用程序反编译工具javap ~

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

【Java可执行命令】(四)反编译工具javap:深入解析应用程序反编译工具javap ~

Java可执行命令详解之javap

在这里插入图片描述

javap是Java开发工具包(JDK)提供的一个命令行工具,用于反编译Java字节码。它旨在帮助开发人员深入了解和分析已编译的Java类文件。

javap可以将Java类文件解析为易于阅读的文本形式,展示其中的信息以及反编译出类的结构、方法、字段、常量池等信息。通过阅读和分析这些信息,开发人员可以更好地理解Java类的内部实现,并进行性能调优、代码审查等操作。

javap主要有以下作用:

  • 展示Java类的结构:可以从字节码级别上查看类的继承关系、方法和字段的信息;
  • 反编译Java字节码:将已编译的Java类文件转化为人可读的源代码形式,以便进行分析和理解。

javap通过解析Java类文件的字节码数据,并根据Java虚拟机规范定义的格式和约定,将其转化为易于阅读的文本形式。它使用反射和解析技术来获取类的结构和信息,并进行适当的格式转换和展示。

优点

  • 提供了一种方式来观察高级Java代码背后的底层字节码;
  • 可以帮助开发人员更好地理解Java类,并对其进行调试和优化;
  • 通过查看反编译的源代码,可以学习他人代码的实现细节。

缺点

  • 反编译出来的源代码可能不够清晰和易读,因为字节码和原始Java代码之间存在一些语义上的差异;
  • javap只能处理已编译的类文件,无法直接作用于源代码。

3.1 语法格式

javap的使用语法格式如下:

javap [options] 

其中,[options]为可选参数列表,表示要解析的Java类名称。

javap命令支持许多可选参数来控制反编译过程。汇总全部的可选参数如下表:

参数作用说明
-version版本信息
-verbose输出附加信息
-l输出行号和本地变量表
-public仅显示公共类和成员
-protected显示受保护的/公共类和成员
-package显示程序包/受保护的/公共类和成员 (默认)
-p-private显示所有类和成员
-c对代码进行反汇编
-s输出内部类型签名
-sysinfo显示正在处理的类的系统信息 (路径, 大小, 日期, MD5 散列)
-constants显示最终常量
-classpath 指定查找用户类文件的位置
-cp 指定查找用户类文件的位置
-bootclasspath 覆盖引导类文件的位置

下面主要介绍以下一些常用的 javap 可选参数:

  • -l: 显示行号和局部变量表信息;
  • -c: 显示Java字节码指令;
  • -s: 显示内部类型签名;
  • -verbose: 详细输出各个类的除了方法主体以外的信息;
  • -version: 显示版本信息。

3.1.1 可选参数:-l

javap -l命令用于在输出中显示行号和局部变量表信息。如果不使用-l选项,则只会显示基本的类和方法信息。下面是一个使用案例:

先使用 javac命令将Java源代码编译为字节码文件,成功编译后,将会生成一个.class的文件。然后就可以使用javap -l <类名>命令查看该类的字节码信息。在终端中执行以下命令:

javap -l MyClass

运行上述命令后,将显示如下输出:

Compiled from "MyClass.java"public class com.xiaoshan.MyClass {  public com.xiaoshan.MyClass();    LineNumberTable:      line 5: 0    LocalVariableTable:      Start  Length  Slot  Name   Signature          0       5     0  this   Lcom/xiaoshan/MyClass;  public static void main(java.lang.String[]);    LineNumberTable:      line 7: 0      line 8: 8    LocalVariableTable:      Start  Length  Slot  Name   Signature          0       9     0  args   [Ljava/lang/String;}

这个输出告诉我们MyClass类有两个成员方法:默认的构造函数MyClass()和静态方法main(String[])。并且还打印出来了行号和局部变量表信息。

3.1.2 可选参数:-c

javap -c命令用于在输出中显示字节码指令信息。下面是一个使用案例:

在终端中执行以下命令:

javap -c MyClass

运行上述命令后,会输出包含字节码指令的详细列表。每个指令都与其对应的操作和参数一起显示。显示如下输出:

Compiled from "MyClass.java"public class com.xiaoshan.MyClass {  public com.xiaoshan.MyClass();    Code:       0: aload_0       1: invokespecial #1                  // Method java/lang/Object."":()V       4: return  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}

在以上示例中,我们可以看到反汇编的 MyClass 类的 默认的构造函数MyClass()和静态方法main(String[])的字节码指令列表。
通过使用 javap -c 命令,你可以深入了解 Java 字节码,并查看所编译类文件中的相应指令。这对于理解代码的底层实现和进行调试非常有用。

3.1.3 可选参数:-s

javap -s 命令可以显示与指定类相关的字节码指令及其源代码的符号信息。以下是关于该命令的作用和使用方式的演示:

使用 javap -s MyClass 命令来查看 MyClass.class 文件的字节码指令及其对应的源代码符号信息:

javap -s MyClass

运行上述命令后,将输出包含字节码指令和源代码符号信息的详细列表。每个指令都与其对应的操作、参数和源代码行号一起显示。
输出结果:

Compiled from "MyClass.java"public class com.xiaoshan.MyClass {public com.xiaoshan.MyClass(); descriptor: ()Vpublic static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V}

在以上示例中,我们可以看到反汇编的 MyClass 类的 main 方法的字节码指令及其源代码符号信息。

通过使用 javap -s 命令,你可以深入了解 Java 字节码及其与源代码之间的映射关系。这对于调试和理解代码执行非常有用,因为它提供了包括本地变量、操作数栈、异常处理器等在内的更多详细信息。

3.1.4 可选参数:-verbose

javap -verbose 是一个用于反汇编 Java 字节码并显示更详细信息的命令,它可以显示与指定类相关的字节码指令、常量池、方法、字段和其他类信息。

以下是关于该命令的作用和使用方式的演示:

使用 javap -verbose MyClass 命令来查看 MyClass.class 文件的更详细反汇编信息:

javap -verbose MyClass

运行上述命令后,将输出包含字节码指令、常量池、方法、字段和其他类信息的详细列表。

输出结果:

Classfile /C:/Users/86182/IdeaProjects/untitled15/class="lazy" data-src/com/xiaoshan/MyClass.class  Last modified 2023-6-28; size 551 bytes  MD5 checksum 349388dc7403df8ac63066c97760fc56  Compiled from "MyClass.java"public class com.xiaoshan.MyClass  minor version: 0  major version: 52  flags: ACC_PUBLIC, ACC_SUPERConstant pool:   #1 = Methodref          #6.#20         // java/lang/Object."":()V   #2 = Fieldref           #21.#22        // java/lang/System.out:Ljava/io/PrintStream;   #3 = String             #23            // Hello world!   #4 = Methodref          #24.#25        // java/io/PrintStream.println:(Ljava/lang/String;)V   #5 = Class              #26            // com/xiaoshan/MyClass   #6 = Class              #27            // java/lang/Object   #7 = Utf8                  #8 = Utf8               ()V   #9 = Utf8               Code  #10 = Utf8               LineNumberTable  #11 = Utf8               LocalVariableTable  #12 = Utf8               this  #13 = Utf8               Lcom/xiaoshan/MyClass;  #14 = Utf8               main  #15 = Utf8               ([Ljava/lang/String;)V  #16 = Utf8               args  #17 = Utf8               [Ljava/lang/String;  #18 = Utf8               SourceFile  #19 = Utf8               MyClass.java  #20 = NameAndType        #7:#8          // "":()V  #21 = Class              #28            // java/lang/System  #22 = NameAndType        #29:#30        // out:Ljava/io/PrintStream;  #23 = Utf8               Hello world!  #24 = Class              #31            // java/io/PrintStream  #25 = NameAndType        #32:#33        // println:(Ljava/lang/String;)V  #26 = Utf8               com/xiaoshan/MyClass  #27 = Utf8               java/lang/Object  #28 = Utf8               java/lang/System  #29 = Utf8               out  #30 = Utf8               Ljava/io/PrintStream;  #31 = Utf8               java/io/PrintStream  #32 = Utf8               println  #33 = Utf8               (Ljava/lang/String;)V{  public com.xiaoshan.MyClass();    descriptor: ()V    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 5: 0      LocalVariableTable:        Start  Length  Slot  Name   Signature            0       5     0  this   Lcom/xiaoshan/MyClass;  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 7: 0        line 8: 8      LocalVariableTable:        Start  Length  Slot  Name   Signature            0       9     0  args   [Ljava/lang/String;}SourceFile: "MyClass.java"

在以上示例中,我们可以看到反汇编的 MyClass 类的文件信息、版本信息、类访问标志、常量池、方法信息和其他相关信息。

通过使用 javap -verbose 命令,你可以深入了解 Java 字节码及其与类结构、常量池和其他组件之间的关联。这对于分析代码执行过程和理解内部实现非常有用。

3.1.5 可选参数:-version

javap -version 可以用来查看类文件的版本信息的。以下是关于该命令的作用和使用方式的演示:

使用 javap -version MyClass 命令来查看 MyClass.class 文件的版本信息:

javap -version MyClass

运行上述命令后,将输出 MyClass.class 文件的版本等信息。 输出结果:

1.8.0_162Compiled from "MyClass.java"public class com.xiaoshan.MyClass { public com.xiaoshan.MyClass(); public static void main(java.lang.String[]);}

在以上示例中,我们可以看到反汇编的 MyClass 类的类文件版本为 1.8.0_162。
通过使用 javap -version 命令,你可以查看指定 Java 类的类文件版本信息。这对于了解类的兼容性和所需的 Java 运行时环境版本有用。

javap广泛应用于以下场景:

  • 代码审查:通过查看反编译的源代码,可以对他人代码的实现细节进行分析和评估;
  • 性能调优:可以通过阅读字节码指令、查看局部变量信息等来进行性能分析和优化;
  • 学习和教学:对于想深入理解Java语言机制、字节码执行等底层原理的学生和教师,javap提供了一种友好的方式来观察和学习。

在使用 javap时需要注意以下事项:

  • javap只能处理已编译的类文件(.class文件),不能直接作用于源代码(.java文件);
  • 反编译结果可能不完全等同于原始Java代码,因为字节码和源代码之间存在语义上的差异;
  • javap只能解析公共类和成员,默认情况下无法访问非公共或非静态成员。

javap是一个有用的工具,用于反编译Java字节码,了解和分析类的内部实现和结构。它为开发人员提供了一个透视Java代码背后的底层视角,并可以帮助进行性能调优、代码审查和学习。

然而,它仅限于处理已编译的类文件,并且反编译的源代码可能与原始Java代码存在一些语义差异。因此,在使用 javap时需要注意其局限性,并结合其他工具和技术来进行全面的分析和理解。

来源地址:https://blog.csdn.net/LVSONGTAO1225/article/details/131476263

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

【Java可执行命令】(四)反编译工具javap:深入解析应用程序反编译工具javap ~

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录