什么是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

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

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

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

  2. java 类文件_Java类文件概述

    所谓 Java 类文件,就是通常用 javac 编译器产生的 .class 文件.这些文件具有严格定义的格式. Java 源文件经过 javac 编译器编译之后,将会生成对应的二进制文件(如下图所示) ...

  3. 如何“反编译” Java类文件? [关闭]

    我可以使用什么程序来反编译类文件? 我实际上会得到Java代码,还是仅仅是JVM汇编代码? 关于该站点上的Java性能问题,我经常看到已经"反编译" Java类文件以查看编译器如何 ...

  4. Java类Demo中存在_Java中的数据类型转换

    先来看一个题: Java类Demo中存在方法func0.func1.func2.func3和func4,请问该方法中,哪些是不合法的定义?( ) public class Demo{ float fu ...

  5. 【深入理解JVM】Java类文件的基本结构

    Java类文件(.class文件)是一个为已编译Java程序仔细定义的格式.Java源代码被编译成能够被任何JVM加载和执行的类文件.在被JVM加载之前,类文件可能是由网络传输而来. 类文件是独立于底 ...

  6. java asm tree_使用ASM 4处理Java类文件–第二部分:Tree API

    java asm tree 什么是ASM树API: ASM树API是ASM的一部分,可让您创建/修改内存中的类. 该类被视为信息树. 像整个类一样,它是ClassNode的实例,其中包含FieldNo ...

  7. 使用ASM 4处理Java类文件–第二部分:Tree API

    什么是ASM树API: ASM树API是ASM的一部分,可让您创建/修改内存中的类. 该类被视为信息树. 像整个类一样,它是ClassNode的实例,其中包含FieldNode对象列表,MethodN ...

  8. 使用ASM 4处理Java类文件–第一部分:世界,您好!

    什么是ASM :ASM是一个用于处理Java字节码的开源Java库. 因此,它具有与Apache BCEL相同的目的. 由于本文假定读者具有Java类文件格式的某些知识,因此建议在此处进行阅读. 那么 ...

  9. Java 向文件中追加数据

    java向文件中追加数据内容. 使用filewrite()方法向文件中追加数据 完整代码 import java.io.*;public class Main {public static void ...

最新文章

  1. 【转载】iOS堆和栈的理解
  2. 查看linux 服务器有多少CPU
  3. 微信小程序前端框架/UI组件
  4. 【数字信号调制】基于ASK+OOK+BPSK+8PSK+QPSK+AM多种算法实现信号调制解调含Matlab源码
  5. 跑马灯广告语的实现过程,并且自定义marquee,解决焦点抢占问题.
  6. 反转一个英语句子c++
  7. 获取ftp服务器文件,ftp获取服务器文件
  8. gensim中word2vec API参数说明
  9. Pyqt设计界面时无法显示图片问题
  10. 会PLC也能玩转机器视觉(一)
  11. 阿里云部署数据库(遇到的问题及解决方案)
  12. 信噪比(一些概念,公式推导,实验分析)
  13. JS标签中 阻止默认事件的发生
  14. 程序员中的奇葩,使用php构建魔兽世界
  15. java线程池介绍(一)
  16. Mac 如何使用外部存储设备,移动硬盘备份 iPhone 数据
  17. Python:使用API——使用Pygal可视化仓库
  18. git status怎么操作_git操作-方向对了,就不怕路远了!-51CTO博客
  19. vlc android局域网rtsp,VLC mosaic分屏显示多路RTSP媒体流问题。
  20. 2021威海高考成绩查询,2021年威海夏季高考时间公布

热门文章

  1. JavaFX UI控件教程(十七)之Slider
  2. baiduTemplate / artTemplate
  3. 44个Java代码性能优化总结
  4. 去BAT面试完的Mysql面试题总结(55道)
  5. 漫画:什么是SHA系列算法
  6. java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized
  7. 让java的多重继承成为现实!
  8. React中jsx的规则
  9. java 组件化_(原创)搭建一个组件化的监控平台
  10. 如何修改服务器mac地址,如何修改服务器mac地址