命令基本概述

javap是JDK自带的反汇编器,可以查看java编译器为我们生成的字节码。通过它,可以对照源代码和字节码,从而了解很多编译器内部的工作。可以在命令行窗口先用javap -help看下javap工具支持的选项:C:\>javap -help

C:\>javap -help

Usage: javap <options> <classes>...

where options include:

   -c                      输出类中各方法的未解析的代码,即构成java字节码的指令

   -classpath <pathlist>       指定javap用来查找类的路径。目录用:分隔

   -extdirs <dirs>             覆盖搜索安装方式扩展的位置,扩展的缺省位置为jre/lib/ext

   -help                    输出帮助信息

   -J<flag>                  直接将flag传给运行时系统

   -l                       输出行及局部变量表

   -public                   只显示public类及成员

   -protected                只显示protected和public类及成员。

   -package                 只显示包、protected和public类及成员,,这是缺省设置

   -private                  显示所有的类和成员

   -s                        输出内部类型签名

   -bootclasspath <pathlist>    指定加载自举类所用的路径,如jre/lib/rt.jar或i18n.jar

   -verbose                 打印堆栈大小、各方法的locals及args参数,以及class文件的编译版本

参数说明

平时一般用-c选项用得比较多,该命令用于列出每个方法所执行的JVM指令,并显示每个方法的字节码的实际作用。可以写个HelloWorld的程序来测试一下该命令。

public class HelloWorld {

         public static void main(String[] args){

           System.out.println("Hello World!");

         }

}

$ javap -cHelloWorld在将该java类编译生成HelloWorld.class文件后,即可通过javap进行具体的反编译分析。如:

Compiled from "HelloWorld.java"

public class HelloWorld extends java.lang.Object{

public HelloWorld();

  Code:

   :   aload_0

   :   invokespecial   #; //Method java/lang/Object."<init>":()V

   :   return

public static void main(java.lang.String[]);

  Code:

   :   getstatic       #; //Field java/lang/System.out:Ljava/io/PrintStream;

   :   ldc     #; //String Hello World!

   :   invokevirtual   #; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

   :   return

}

0:   getstatic       #2; //Fieldjava/lang/System.out:Ljava/io/PrintStream;为了能够更清晰的了解javap反编译生成的字节码,下面来分析main方法中的指令,vcb用于转换Java语言中的代码行System.out.println("HelloWorld!");

最初始的整数表示方法中指令的偏移量,因此第一个指令是从0开始的。它表示的是从java.lang.system对象的out字段中检索PrintStream对象,getstatic指令即是将该静态域压缩并放到操作数栈中。按下来的指令则是引用一个地址,在当前情况下,指的是“#2;//Field java/lang/System.out:Ljava/io/PrintStream;”。在此你将会发现该域信息并没有直接嵌入进来。相反它是通过类似java类中的其它常量一样,该域信息被存储在一个共享池中。采用该常量池的方式能够减小字节码指令的长度。这也就是为什么指令中仅仅保存常量池的地址索引,而非所有的信息。在本示例中,域信息被存放在常量池中标识有#2的位置。

3:   ldc    #3; //String Hello World!

其实分析完第一条指令后,将非常容易的猜测到第二条指令的具体含义了。ldc(load constant)指令用于将HelloWorld!字符串压入至栈中。

5:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

该指令将调用println方法,它将从操作栈中弹出两个参数。千成别忘记了象println这样的实例方法其实是包含了两个参数的,一个是字符串,另一个是隐式的this索引。

上面的minor version: 0和majorversion: 49就是编译Worke.class时使用的jdk编译版本号。

但是它并不是我们所熟悉的jdk版本号(比如jdk1.5)。

不过我们可以把从 JDK 1.1 到 JDK 1.7 编译器编译出的 class 的默认minor.major version 汇总下就知道对应关系了。

JDK 编译器版本

target 参数

十六进制 minor.major

十进制 minor.major

jdk1.1.8

不能带 target 参数

00 03 00 2D

45.3

jdk1.2.2

不带(默认为 -target 1.1)

00 03 00 2D

45.3

jdk1.2.2

-target 1.2

00 00   00 2E

46.0

jdk1.3.1_19

不带(默认为 -target 1.1)

00 03 00 2D

45.3

jdk1.3.1_19

-target 1.3

00 00   00 2F

47.0

j2sdk1.4.2_10

不带(默认为 -target 1.2)

00 00   00 2E

46.0

j2sdk1.4.2_10

-target 1.4

00 00   00 30

48.0

jdk1.5.0_11

不带(默认为 -target 1.5)

00 00   00 31

49.0

jdk1.5.0_11

-target 1.4 -source 1.4

00 00   00 30

48.0

jdk1.6.0_01

不带(默认为 -target 1.6)

00 00   00 32

50.0

jdk1.6.0_01

-target 1.5

00 00   00 31

49.0

jdk1.6.0_01

-target 1.4 -source 1.4

00 00   00 30

48.0

jdk1.7.0

不带(默认为 -target 1.6)

00 00   00 32

50.0

jdk1.7.0

-target 1.7

00 00   00 33

51.0

jdk1.7.0

-target 1.4 -source 1.4

00 00   00 30

48.0

Apache Harmony 5.0M3

不带(默认为 -target 1.2)

00 00   00 2E

46.0

Apache Harmony 5.0M3

-target 1.4

00 00   00 30

48.0

【JVM命令系列】javap的更多相关文章

  1. 【JVM命令系列】jstat

    命令基本概述 Jstat是JDK自带的一个轻量级小工具.全称"Java Virtual Machine statistics monitoring tool",它位于java的bi ...

  2. 【JVM命令系列】jstack

    jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使 ...

  3. 【JVM命令系列】jmap

    命令基本概述 Jmap是一个可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本.打印出某个java进程(使用pid)内存内的,所有'对象'的情况(如:产生那些对象,及其数量 ...

  4. JVM基础系列第15讲:JDK性能监控命令

    查看虚拟机进程:jps 命令 jps 命令可以列出所有的 Java 进程.如果 jps 不加任何参数,可以列出 Java 程序的进程 ID 以及 Main 函数短名称,如下所示. $ jps 6540 ...

  5. JVM基础系列第5讲:字节码文件结构

    温馨提示:此篇文章长达两万字,图片50多张,内容非常多,建议收藏后再看. 前面我们说到 Java 虚拟机使用字节码实现了跨平台的愿景,无论什么系统,我们都可以使用 Java 虚拟机解释执行字节码文件. ...

  6. JVM基础系列第14讲:JVM参数之GC日志配置

    说到 Java 虚拟机,不得不提的就是 Java 虚拟机的 GC(Garbage Collection)日志.而对于 GC 日志,我们不仅要学会看懂,而且要学会如何设置对应的 GC 日志参数.今天就让 ...

  7. JVM基础系列第13讲:JVM参数之追踪类信息

    我们都知道 JVM 在启动的时候会去加载类信息,那么我们怎么得知他加载了哪些类,又卸载了哪些类呢?我们这一节就来介绍四个 JVM 参数,使用它们我们就可以清晰地知道 JVM 的类加载信息. 为了方便演 ...

  8. JVM基础系列第11讲:JVM参数之堆栈空间配置

    JVM 中最重要的一部分就是堆空间了,基本上大多数的线上 JVM 问题都是因为堆空间造成的 OutOfMemoryError.因此掌握 JVM 关于堆空间的参数配置对于排查线上问题非常重要. tips ...

  9. JVM基础系列第10讲:垃圾回收的几种类型

    我们经常会听到许多垃圾回收的术语,例如:Minor GC.Major GC.Young GC.Old GC.Full GC.Stop-The-World 等.但这些 GC 术语到底指的是什么,它们之间 ...

随机推荐

  1. 获取ip地址及城市信息

    大家好,今天给大家分享的是一个简单的知识获取登录用户的ip地址及城市信息,lz是一个小白,如果有哪些错误的地方  欢迎大家指出 东西很简单,直接上代码 [HttpPost] public string ...

  2. Promise的用法

    promise.then().promise.catch().Promise.all()... Promise 构造函数接受一个函数作为参数,该函数的2个参数分别是 resolve 和 reject. ...

  3. IEnumerable和IQueryable接口

    之间的区别 IQueryable继承于IEnumerable IEnumerable:IEnumerable<T> 泛型类在调用自己的SKip 和 Take 等一些扩展方法之前数据就已经加 ...

  4. 初入PHP,(for循环~水仙花数)

    找出100-999之间的所有"水仙花数".所谓水仙花数是指一个三位 数,各位数字的立方和等于该数本身.(如153次方=1的3次方+5的3次方+3的3次方)并输出这些数字 想想153 ...

  5. lua代码的加载

    lua代码的加载 Openresty是什么 OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台,通过把lua嵌入到Nginx中,使得我们可以用轻巧的lua语言进行nginx的 ...

  6. java中覆盖必须满足的约束

    子类方法的名称,参数何返回类型必须与父类一致. 子类方法不能缩小父类方法的访问权限 子类方法不能抛出比父类方法更多的异常 方法覆盖只存在于子类和父类,同一个类中方法只能被重载 父类的静态方法不能被子类 ...

  7. 201521123051《Java程序设计》第十一周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. Java多线程同步的方法: (1)同步方法:即有synchronized关键字修饰的方法. 由于java的每个对象 ...

  8. 快递鸟顺丰物流api接口对接多种方法整理

    目前很多自营电商平台.ERP系统.仓储系统.快递柜企业,对物流模块数据需求还是比较旺盛的.之前有介绍过简单的接口对接方法,这次给大家整理介绍两种快递数据的获取方法. 接口秘钥可以向顺丰公司申请,或者一 ...

  9. lintcode.177 把排序数组转换为高度最小的二叉搜索树

    把排序数组转换为高度最小的二叉搜索树    描述 笔记 数据 评测 给一个排序数组(从小到大),将其转换为一棵高度最小的排序二叉树. 注意事项 There may exist multiple val ...

  10. jquery-easyUI第一篇【介绍、入门、使用常用的组件】

    什么是easyUI 我们可以看官方对easyUI的介绍: easyUI就是一个在Jquery的基础上封装了一些组件-.我们在编写页面的时候,就可以直接使用这些组件-非常方便-easyUI多用于在后台的 ...