java javap

什么是Javap,如何使用它以及何时要反汇编类文件?

作为Java开发工具包(JDK)的一部分,我们可以使用许多工具,这些工具有助于更好地理解Java代码。 这些工具之一是javap命令,它使我们能够在后台传递Java类文件。

在下面的文章中,我们将研究javap,了解它如何帮助我们并确切地了解我们如何使用它。 代码,反汇编!

什么是javap?

javap是一个命令行工具,可分解Java类文件:它分解了我们的类文件,并揭示了其中的内容。 该工具将二进制格式的类文件转换为人类可读的代码。 好吧,对于某些人。

javap提供了许多输出,这些输出根据我们感兴趣的数据而有所不同。默认情况下,javap打印每个类的非私有成员的声明。

至于javap中的p代表什么,所有证据都指向“打印”,因为javap命令会打印出类中的字节码。

我们可以使用javap的一种好方法是探索异常。 如果您想提高自己的知识并了解引发异常时会发生什么,请查看我们的帖子,了解有关Java异常的令人惊讶的真相 。

在我们的类中使用javap

既然我们知道了javap是什么,该是在我们的代码上尝试使用它的时候了。 我们通过键入命令,选择一个选项并添加类名称来做到这一点:

javap [选项]类名

正如我们指出的,这些选项(也可以称为标志)将决定我们的输出是什么。 我们可以从许多标志中进行选择,包括:

  • -l –输出行和局部变量表
  • -public –仅显示公共班级和成员
  • -protected –仅显示受保护的和公开的班级和成员
  • -package –仅显示软件包,受保护的和公共的类和成员
  • -p –显示所有班级和成员
  • -Jflag –将标志直接传递到运行时系统
  • -s –打印内部类型签名
  • -sysinfo –显示正在处理的类的系统信息(路径,大小,日期,MD5哈希)
  • -constants –显示静态最终常量
  • -c –打印反汇编的代码
  • -verbose –打印堆栈大小,方法的局部变量和args

用javap深入字节码

在列出了可以使用javap进行的操作之后,现在该弄清楚它的实际工作方式了。 为此,我们创建了一个名为ExampleClass的基本类:

public class ExampleClass
{private int a = 0;private int b = 0;public static void main(String[] args) {System.out.println("Hello world!");}
}

现在让我们在javap的帮助下更深入地研究它。 首先,我们将使用不带任何其他标志的javap命令来打印出非私有成员。 我们的输出是这样的:

$ javap ExampleClassCompiled from "ExampleClass.java"
public class ExampleClass {public ExampleClass();public static void main(java.lang.String[]);
}

如您所见,这是原始代码的漂亮“普通”视图,没有有关私有整数和逻辑的任何信息。 这是一个好的开始,但是如果我们想更深入地了解该怎么办? 让我们尝试使用-c打印出反汇编的代码:

$ javap -c ExampleClassCompiled from "ExampleClass.java"
public class ExampleClass {public ExampleClass();Code:0: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: aload_05: iconst_06: putfield      #2                  // Field a:I9: aload_010: iconst_011: putfield      #3                  // Field b:I14: returnpublic static void main(java.lang.String[]);Code:0: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;3: ldc           #5                  // String Hello world!5: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V8: return
}

现在,我们以某种有点可读的形式保存了字节码,可以在其中识别我们的方法,整数,命令和字符串。 但是,等等,还有更多。 如果我们需要有关该课程的更多信息怎么办? 那是我们冗长的标志可以帮助我们的地方:

$ javap -v ExampleClassClassfile /Users/es/ExampleClass.classLast modified May 22, 2017; size 496 bytesMD5 checksum 7d29362228a3128e67b0c20c8bb54ee1Compiled from "ExampleClass.java"
public class ExampleClassSourceFile: "ExampleClass.java"minor version: 0major version: 51flags: ACC_PUBLIC, ACC_SUPER
Constant pool:#1 = Methodref          #8.#20         //  java/lang/Object."<init>":()V#2 = Fieldref           #7.#21         //  ExampleClass.a:I#3 = Fieldref           #7.#22         //  ExampleClass.b:I#4 = Fieldref           #23.#24        //  java/lang/System.out:Ljava/io/PrintStream;#5 = String             #25            //  Hello world!#6 = Methodref          #26.#27        //  java/io/PrintStream.println:(Ljava/lang/String;)V#7 = Class              #28            //  ExampleClass#8 = Class              #29            //  java/lang/Object#9 = Utf8               a#10 = Utf8               I#11 = Utf8               b#12 = Utf8               <init>#13 = Utf8               ()V#14 = Utf8               Code#15 = Utf8               LineNumberTable#16 = Utf8               main#17 = Utf8               ([Ljava/lang/String;)V#18 = Utf8               SourceFile#19 = Utf8               ExampleClass.java#20 = NameAndType        #12:#13        //  "<init>":()V#21 = NameAndType        #9:#10         //  a:I#22 = NameAndType        #11:#10        //  b:I#23 = Class              #30            //  java/lang/System#24 = NameAndType        #31:#32        //  out:Ljava/io/PrintStream;#25 = Utf8               Hello world!#26 = Class              #33            //  java/io/PrintStream#27 = NameAndType        #34:#35        //  println:(Ljava/lang/String;)V#28 = Utf8               ExampleClass#29 = Utf8               java/lang/Object#30 = Utf8               java/lang/System#31 = Utf8               out#32 = Utf8               Ljava/io/PrintStream;#33 = Utf8               java/io/PrintStream#34 = Utf8               println#35 = Utf8               (Ljava/lang/String;)V
{public ExampleClass();flags: ACC_PUBLICCode:stack=2, locals=1, args_size=10: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: aload_05: iconst_06: putfield      #2                  // Field a:I9: aload_010: iconst_011: putfield      #3                  // Field b:I14: returnLineNumberTable:line 1: 0line 3: 4line 4: 9public static void main(java.lang.String[]);flags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=1, args_size=10: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;3: ldc           #5                  // String Hello world!5: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V8: returnLineNumberTable:line 7: 0line 8: 8
}

很多行在我们面前展开。 我们可以看到以下内容:

1.元数据–此类文件的位置,上次修改时间以及具有其唯一ID的类哈希
2.常量池–结构表,它引用ClassFile结构及其子结构中的各种常量。 它保存类,接口,类实例,字段名称,字符串常量或数组的符号信息。
3.字节码–用JVM可以“读取”的语言编写的指令集

在OverOps,我们使用javap作为研究工具来挖掘类内部。 我们最近使用它来发现IBM J9的工作方式,为使用此JVM的开发人员提供支持。 如果您想了解更多有关我们如何帮助团队减少调试时间并知道代码在何时何地中断的原因, 请单击此处以安排演示 。

现在我们知道了如何使用javap,是时候回答一个重要的问题了:

到底有什么好处呢?

Javap很酷,特别是如果您是像我们这样的数据迷并且想知道代码背后发生了什么时。 但是除了不错的代码探索冒险外,它也非常有用。

对于原始源代码不可用的情况,它可能会派上用场,其中显示了可以使用的方法。 它还可以帮助找出别人的代码或3rd party类中的内容。

我们还可以将javap用作Java类的类验证器,以确保每个加载的类文件都以适当的方式进行结构化。

刚开始,javap就像是一根魔杖,可以在代码内为我们提供所有信息,但它并不是对我们所面临的每个问题的完整解决方案。 它可能会帮助“逆向工程”某些代码,但这更多是一个复杂难题的线索。

如果您正在寻找一种将javap字节码输出转换为功能性Java代码的方法,而不仅仅是“数据列表”,那么您将需要反编译工具(如JD , Mocha等)的帮助。

最后的想法

尽管您不会经常使用它,但是javap是一个有用的工具,请牢记。 除了它是一个很酷的“技巧”之外,它还更深入地介绍了Java代码,向我们展示了幕后发生的事情以及JVM如何使用我们的代码。

翻译自: https://www.javacodegeeks.com/2017/06/javap-usage-unfolds-whats-hidden-inside-java-class-files.html

java javap

java javap_javap的用途不断发展:您的Java类文件中隐藏了什么?相关推荐

  1. javap的用途不断发展:您的Java类文件中隐藏了什么?

    什么是Javap,如何使用它以及何时要反汇编类文件? 作为Java开发工具包(JDK)的一部分,我们可以使用许多工具,这些工具有助于更好地理解Java代码. 这些工具之一是javap命令,它为我们提供 ...

  2. java 字符串池 原理_《Java虚拟机原理图解》1.2.2、Class文件中的常量池详解(上)...

    注意: 对于某个类而言,其class文件中至少要有两个CONSTANT_Class_info常量池项,用来表示自己的类信息和其父类信息.(除了java.lang.Object类除外,其他的任何类都会默 ...

  3. java class文件常量池_《Java虚拟机原理图解》 1.2.3、Class文件中的常量池详解(下)...

    Java内存区域         1.程序计数器(Program Counter Register)(线程私有的)         2.Java虚拟机栈 (Java Virtual Machine S ...

  4. java pdfbox 提取pdf 标题_java – 使用pdfbox从PDF文件中提取文本

    我试图使用pdfbox从PDF文件中提取文本,但不是作为命令行工具,而是在我的 Java应用程序中.我正在使用jsoup下载pdf. res = Jsoup .connect(host+action) ...

  5. java中secretkey,java生成秘钥key,并保存秘钥到文件中

    本例子采用的是Java的对称加密其中的一种方式(3DES),其他的加密方式也类似.生成一个key秘钥,发送方使用生成的key秘钥进行加密操作,然后把生成的key秘钥保存到文件中,提供给需要解密的一方使 ...

  6. java 格式化json_JAVA 格式化JSON数据并保存到json文件中的实例

    使用fastjson格式化json数据并保存到文件 /** * 将JSON数据格式化并保存到文件中 * @param jsonData 需要输出的json数 * @param filePath 输出的 ...

  7. java如何用LOG打印日志并输出信息到文件中

    使用log4j.jar.log4j 是apache 提供的记录日志的jar 档. 下载地址:http://logging.apache.org/log4j/1.2/download.html 除了这个 ...

  8. java程序中类的成员变量定义在_.在类体中,变量定义部分所定义的变量称为类的________。...

    .在类体中,变量定义部分所定义的变量称为类的________. .成员变量在整个类内都有效,________变量只在定义它的方法内有效. .Java中成员变量又分为实例成员变量和________. . ...

  9. Java海康威视摄像头实时预览视频流保存到指定文件中

    海康威视摄像头实时预览视频流保存到文件中 目前在开发海康威视sdk ,IPC设备,视频回调用的是官方提供的Demo中的(fRealDataCallBack ) 在最下面代码可以设置Thread.sle ...

最新文章

  1. VSTO Office二次开发对PPT自定义任务窗格测试
  2. KM(知识管理)与SharePoint Portal
  3. 教程:Hibernate,JPA和Spring MVC –第2部分
  4. 基于直方图处理的图像增强
  5. innerHTML和value的区别
  6. 寻找链表倒数第k个节点
  7. eclipse启动springboot项目_多模块项目中的一个Spring Boot启动错误
  8. [Ext JS 4] 布局之实战二 - 中间区块不会自动伸展 (tab)续
  9. bzoj 1260: [CQOI2007]涂色paint(区间DP)
  10. 台哥算法练习 - 自己写的一个LinkedList
  11. 《大教堂与市集》读后感
  12. 对比学习Python实现
  13. 反编译 APK 的基本步骤
  14. google四件套之Dagger2。从入门到爱不释手,之:Dagger2华丽使用在MVP框架中
  15. 玻尔原子模型中各轨道半径、轨道能量公式推导
  16. testbed笔记:头文件里的函数
  17. xhEditor富文本编辑器的使用说明
  18. 如何批量查询百度指数
  19. 轻快步伐远不足以跟上轻快心情
  20. 语义分割评估指标MIOU

热门文章

  1. 线段树/扫描线问卷调查反馈——Rmq Problem / mex(主席树),Boring Queries(二分+st表+主席树),Colorful Squares(扫描线)
  2. jzoj4815-ksum【堆】
  3. nssl1322,jzoj(初中)2109-清兵线【dp】
  4. 【DP】【高精】幸运票 (jzoj 2122)
  5. Codeforces1142D
  6. play框架入门操作
  7. 告诉你,Spring Boot 真是个牛逼货
  8. Java中CAS详解
  9. 【深入理解JVM】:类加载器与双亲委派模型
  10. 面象对象设计6大原则之三:里氏替换原则