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

news2025/1/12 8:39:27

Java可执行命令详解之javap

  • 1️⃣ 概念
  • 2️⃣ 优势和缺点
  • 3️⃣ 使用
    • 3.1 语法格式
      • 3.1.1 可选参数:-l
      • 3.1.2 可选参数:-c
      • 3.1.3 可选参数:-s
      • 3.1.4 可选参数:-verbose
      • 3.1.5 可选参数:-version
  • 4️⃣ 应用场景
  • 5️⃣ 注意事项
  • 🌾 总结

在这里插入图片描述

1️⃣ 概念

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

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

javap主要有以下作用:

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

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

2️⃣ 优势和缺点

优点

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

缺点

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

3️⃣ 使用

3.1 语法格式

javap的使用语法格式如下:

javap [options] <classname>

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

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

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

下面主要介绍以下一些常用的 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."<init>":()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: ()V

public 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/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_SUPER
Constant pool:
   #1 = Methodref          #6.#20         // java/lang/Object."<init>":()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               <init>
   #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          // "<init>":()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."<init>":()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_162
Compiled 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 运行时环境版本有用。

4️⃣ 应用场景

javap广泛应用于以下场景:

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

5️⃣ 注意事项

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

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

🌾 总结

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/703932.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

6.21、设计模式 单例设计模式

1 设计模式&#xff08;Design pattern&#xff09; 代表了最佳的实践&#xff0c;通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来…

好用又智能笔记类工具有哪些?

在工作和生活中&#xff0c;我们经常面临大量信息和任务需要记录和整理。好用又智能的笔记类工具成为了办公人士提高工作效率和组织信息的必备利器。 敬业签笔记工具支持分类记录笔记&#xff0c;可以根据不同的主题或项目进行整理。无论是工作笔记、学习笔记还是个人生活记录…

OpenFeign——请求其他服务时传递token信息

文章目录 前言准备流程初测定义nacos-product子服务定义服务的消费方 cloudalibaba-openfeign-server初步测试结论 设置cloudalibaba-openfeign-server中的feign总结 前言 在实际开发过程中&#xff0c;服务与服务之间都会有比较频繁的通信操作。其次不同用户所需要查询的数据…

【正点原子STM32连载】 第四十七章 SRAM实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html# 第四…

使用inno打包程序流程

1:配置iss文件 ​​​​​​​ 2编译 3.生成安装包文件安装

浅谈建筑项目中的智能照明系统的设计与研究

【摘要】&#xff1a;建筑智能照明工程中智能照明控制系统发展迅速&#xff0c;具有舒适性和节能性两方面优势。智能照明控制系统已经处于模块化高速发展阶段&#xff0c;如今更好的控制方案成为制约系统发展的瓶颈。文章在研究了国内外智能照明系统的基础上&#xff0c;从照明…

【CSS】nth:children以及浏览器内核webkit使用(滚动条样式修改)

&#x1f609;博主&#xff1a;初映CY的前说(前端领域) ,&#x1f4d2;本文核心&#xff1a;nth:children以及浏览器中的webkit使用 前言&#xff1a;在页面的编写中使用了多个标签通常有需求去处理下特殊的样式&#xff0c;我们常见做法是给我们的标签加上一个类或者通过标签选…

【微服务】什么是微服务?-- 全面了解微服务架构

What is Microservices — Edureka 您有没有想过&#xff0c;什么是微服务以及扩展行业如何与它们集成&#xff0c;同时构建应用程序以满足客户的期望&#xff1f; 要了解什么是微服务&#xff0c;您必须了解如何将单体应用程序分解为独立打包和部署的小型微型应用程序。本文将…

力扣 -- 91.解码方法

题目链接&#xff1a;91. 解码方法 - 力扣&#xff08;LeetCode&#xff09; 以下是用动态规划的思想解决这道题目&#xff0c;如果对动态规划五部曲的含义还不是很清楚的老铁可以看看本专栏的第一题动规(10条消息) 力扣 -- 746. 使用最小花费爬楼梯_KOBE 0824 BRYANT的博客-…

软件测试编写文档模板【附文档模板】

一、测试岗位必备的文档 在一个常规的软件测试流程中&#xff0c;会涉及到测试计划、测试方案、测试用例、测试报告的编写&#xff0c;这些文档也是软件测试岗位必须掌握的文档类型。 1、测试计划 测试计划是组织管理层面的文件&#xff0c;从组织管理的角度对一次测试活动进…

华为OD机试真题 Python实现【最小的调整次数】【2023Q1 100分】

目录 一、题目描述二、输入描述三、输出描述四、补充说明五、解题思路六、Python算法源码七、效果展示1、输入2、输出3、说明 一、题目描述 有一个特异性的双端队列&#xff0c;该队列可以从头部或尾部添加数据&#xff0c;但是只能从头部移出数据。 小A依次执行2n个指令往队…

uboot详解(嵌入式学习)

uboot详解 概念详解扩展Windows的“uboot” 概念 U-Boot&#xff08;Unified Bootloader&#xff09;是一个开源的嵌入式系统引导加载程序&#xff0c;也是一种通用的引导加载程序。它主要用于嵌入式系统的启动过程&#xff0c;负责初始化硬件设备、加载操作系统内核和启动应用…

Android Studio 使用 Build Variants 配置测试/正式环境域名等字段

拿测试环境域名和正式环境域名举例&#xff1a;在项目调试和发版过程中可以通过频繁地注释和解开注释来切换正式环境域名和测试环境域名&#xff0c;但此方法过于繁琐&#xff1b;所以可以使用Android Studio的Build Variants根据切换环境来替我们执行切换环境的操作。 在项目…

《HelloGitHub》第 87 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 https://github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 …

可视化对讲广播电话可以用在哪里

可视化对讲广播电话可以用在哪里 可视化对讲广播电话&#xff1a;无处不在的沟通利器 【工地现场】 在矗立的高楼上&#xff0c;工地上忙碌的工人们使用着可视化对讲广播电话。借助高清画面和清晰音频&#xff0c;工作人员可以实时观察工地情况&#xff0c;更好地协调工作&a…

【【51单片机实现LED点阵屏幕和动画显示】】

LED点阵屏幕和驱动代码 我们先搞清楚&#xff17;&#xff14;HC&#xff15;&#xff19;&#xff15;的原理 &#xff53;&#xff46;&#xff52; 特殊功能寄存器声明 &#xff53;&#xff42;&#xff49;&#xff54; 特殊位声明 就举个例子&#xff0c;我们在之前的…

Linux后台运行Python脚本

Linux后台运行Python脚本命令&#xff1a; nohup python webui.py > myout.file 2>&1 &nohup&#xff1a;nohup命令用于不挂断地运行命令python&#xff1a;执行python代码的命令webui.py: python程序脚本源代码>: 打印程序输出信息到指定日志文件中myout.fi…

[vue]使用Element--Tree 树形控件使用props解决自定义slot-scope=“{ node, data }“的对象问题

在未用props定义的情况下&#xff0c;slot-scope"{ node, data }"解析data对象只有data含有lable和children才能识别出内容和子节点 当我获取的数据如下&#xff0c;没有lable和children&#xff0c;使用的是name和childList&#xff0c;如下图所示&#xff1a; 注意…

设计必备的矢量插画素材,这几个网站超齐全。

分享几个设计必备的矢量插画、插图素材网站&#xff0c;建议收藏~ 菜鸟图库 https://www.sucai999.com/searchlist/bianpingchahua----all-0-1.html?vNTYxMjky 菜鸟图库是一个素材非常丰富的网站&#xff0c;这里面涵盖了平面、电商、UI、图片、高清背景、插画、视频、音频等…

【新星计划】技术博客写作技巧经验分享

序言 写技术博客需要一定的专业知识和写作技巧&#xff0c;它是一个很好的方式来分享你的经验和知识&#xff0c;同时也是一个展示你的专业能力和建立自己品牌的机会。 以下是一些准备和建议&#xff0c;希望可以帮助你写出有用和有吸引力的技术博客&#xff1a; 写在前面 我报…