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

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

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

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

相关文章

打砖块小游戏php程序,利用原生js实现html5打砖块小游戏(代码示例)

本篇文章给大家通过代码示例介绍一下利用原生js实现html5打砖块小游戏的方法。有一定的参考价值&#xff0c;有需要的朋友可以参考一下&#xff0c;希望对大家有所帮助。前言PS&#xff1a;本次项目中使用了大量 es6 语法&#xff0c;故对于 es6 语法不太熟悉的小伙伴最好能先了…

si9000阻抗匹配计算_如何在设计之初计算出两层PCB板差分线的阻抗,线宽,间距...

最近在设计一款两层板PCB。板上一些高速信号线&#xff0c;分别是MIMP接口的差分线和USB2.0的差分线。既然是高速线&#xff0c;那么就需要设计成阻抗匹配走线。MIMP差分线需要做100ohm匹配&#xff0c;USB线需要做90ohm匹配。差分线阻抗的计算主要跟线宽&#xff0c;间距&…

oracle查询排序速度慢,Oracle-请问Oracle SQL排序查询慢如何解决

这个原因很简单&#xff1a;SELECT * FROM(SELECT T.*,ROWNUM RN FROM(SELECT * FROM INFO ORDER BY PDATE DESC) T WHERE ROWNUM<2001) WHERE RN>0算一下&#xff0c;如果使用定义在PDATE上的索引&#xff0c;那么拿到这2000个rowid后&#xff0c;还需要做2000次random …

jax-ws cxf_Apache CXF – JAX-WS –简单教程

jax-ws cxf许多Java开发人员都认为Web Service实现的任务艰巨-好吧&#xff0c;没有人能真正责怪他们&#xff0c;尤其是在企业应用程序开发的多年中&#xff0c;这给开发和设计带来了很多复杂性。 对于某些人来说&#xff0c;了解它是构建完整的企业应用程序的下一步-Web服务-…

oracle instance client 下载,安装Oracle Instance Client

不想再装客户端了&#xff0c;个太大了。1、去下载你想要的Instance Clent版本&#xff0c;解压&#xff1b;2、把以前备份的sqlnet.oratnsnames.ora放在解压后的目录&#xff1b;3、配置环境变量变量名:TNS_ADMIN变量值:X:\XXXXXXXX\instantclient_10_24、用记事本保存为XX.re…

写屏障是什么_面试官为什么问内存模型总离不开final关键字,该如何应对?

Java 语言的每个关键字都设计的很巧妙&#xff0c;金雕玉琢&#xff0c;只有深度钻研其中&#xff0c;才知其中懊悔&#xff0c;本文带领大家一起深入理解 Java 内存模型之 final。加我微信好友的不要着急&#xff0c;手机没电了&#xff0c;等我借个充电器之后&#xff0c;再一…

非静态方法可以访问Java中的静态变量/方法吗?

“非静态方法可以访问静态变量或调用静态方法”是Java中有关静态修饰符的常见问题之一&#xff0c;答案是&#xff0c; 是的 &#xff0c;非静态方法可以访问静态变量或调用静态方法。 Java中的方法。 这没有问题&#xff0c;因为有静态成员&#xff0c;即静态变量和静态方法都…

php中$_post怎么用,php – 如何在$_POST []中使用变量

我需要遍历一堆动态生成的字段,但这不起作用&#xff1a;$population_density $_POST[$current_location_id];我有一个页面列表,其人口在一页上;我需要这样做,这样你就可以立刻更新它们.所以我使字段名称动态地对应于location_id.提交帖子时,我需要像这样迭代它们,但似乎你不能…

python输入字母终止_将用户输入限制为字母

我是学python的技术作家。我想写一个验证姓名字段输入的程序&#xff0c;作为实践&#xff0c;将用户输入限制为字母。我在这里看到了一个类似的验证数字(年龄)字段的代码&#xff0c;并将其用于字母表&#xff0c;如下所示&#xff1a;import stringimport rer re.compile(r[…

which oracle linux,(总结)Linux下Oracle11gR2的ORA-00845错误解决方法

PS&#xff1a;前些时间一台演示环境的Oracle 11g for Linux不知什么原因&#xff0c;启动不起来&#xff0c;报错ORA-00845。搜索了下&#xff0c;这个问题是由于设置SGA的大小超过了操作系统/dev/shm的大小。当时解决了没空写总结&#xff0c;今天有点空&#xff0c;总结分享…

oracle编程基本语法,oracle编程基础语法

oracle数据开发编程结构&#xff1a; declare[定义变量]begin[逻辑代码]exception[捕获异常]end&#xff1b;实例&#xff1a;declarea number:1;b number:2;c number;beginc:(a*b)/(ab);dbms_output.put_line(c);exceptionwhen zero_divide thendbms_output.put_line(除数不能…

java8optional_关于Java 8的Optional的介绍

java8optional我最近发现了JDK 8中Optional类型的添加。 Optional类型是避免NullPointerException一种方法&#xff0c;因为从方法中获取Optional返回值的API使用者被“强制”执行“在线”检查&#xff0c;以消耗其实际返回值。 更多细节可以在Javadoc中看到。 可以在此博客文章…

python大文件排序_python实现按创建时间对文件排序

测试中&#xff0c;测试log是经常需要保存一段时间以便于后续查询&#xff0c;但是如果一段时间不删除&#xff0c;会导致硬盘空间变小而影响自动化测试&#xff0c;通常空间太小&#xff0c;自动化测试case就不能调用了&#xff0c;或者即使调用&#xff0c;可能会引起新测试的…

oracle存储过程深入,深入了解oracle存储过程的优缺点

定义&#xff1a;存储过程(Stored Procedure )是一组为了完成特定功能的SQL 语句集&#xff0c;经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象&#xff0c;任何一个设计良好的数据库应用程…

如何在Java 8中使用LocalDateTime格式化/解析日期-示例教程

Java项目中的常见任务之一是将日期格式化或解析为String&#xff0c;反之亦然。 解析日期表示您有一个表示日期的字符串&#xff0c;例如“ 2017-08-3”&#xff0c;并且要将其转换为表示Java中日期的对象&#xff0c;例如Java 8之前版本中的java.util.Date以及LocalDate或Loca…

如何获取当前刀具号_数控刀具的选用原则,如何使用数控刀具?一文全面介绍数控刀具...

数控刀具选用概述学习数控相关知识&#xff0c;最基础的是认识和了解刀具的材料以及选用原则&#xff0c;我们应当了解数控刀具的种类及特点、如何正确选择和使用数控加工刀具&#xff1b;学会根据被加工材料来合理选择数控刀具的材料和切削参数。选用原则&#xff1a;数控车床…

Java命令行界面(第27部分):cli-parser

CLI Parser最初托管在Google Code上&#xff0c;现在已存档在Google Code上 &#xff0c;现在可以在GitHub上使用 。 归档的Google Code项目页面将CLI解析器描述为“使用非常简单&#xff0c;非常小的依赖项”&#xff0c;它使用注释“使非常简洁的主要方法不需要知道如何解析带…

linux系统中如何安装qwt,linux下Qt开发环境中qwt库的安装与使用

qwt的安装与使用安装好qt开发环境后&#xff0c;先去下载qwt库源代码。以我下载的qwt-6.0.1.zip为例&#xff0c;解压得到qwt-6.0.1。1.安装qwt-6.0.1执行下面的命令&#xff1a;1 cd qwt-6.0.12 qmake3 make4 make install这样就完成qwt-6.0.1的安装了&#xff0c;安装的路径是…

moxy json介绍_MOXy的对象图和动态JAXB

moxy json介绍JAXB&#xff08;JSR-222&#xff09;使您可以轻松地将域类的实例转换为XML。 EclipseLink MOXy实现提供了一个称为Dynamic JAXB的扩展&#xff0c;在其中&#xff0c;您可以使用诸如DynamicEntity之类的映射实例代替真实的类​​。 您可以使用采用属性名称的get和…

linux 查看服务器作业,linux – 如何在服务器负载较低时运行作业?

我有一个运行磁盘快照的命令(在EC2上,冻结XFS磁盘并运行EBS快照命令),该命令设置为作为cron作业定期运行.理想情况下,如果在任务计划运行时磁盘被大量使用,我希望能够将命令延迟一段时间.我担心使用nice / ionice可能没有正确的效果,因为我希望脚本在运行时以高优先级运行(即等…