【CSDN常见问题解答】Javap 的使用

现在Java反编译工具或者插件非常多,也非常好用。比如我用的比较多得jd-gui。所以我们可能很少有机会使用到Javap命令。

这里我简单介绍下Javap,带各位入个门。介绍下这个命令不是使用它进行反编译,而是查看java编译器为我们生成 的字节码,通过比较字节码和源代码,我们可以发现很多的问题,一个很重要的作用就是了解很多编译器内部的工作机制。

下面我们通过具体的一个例子来简单的讲讲这个工具的作用,你不需要很深入的使用,这个简单的介绍和简单的使用就可以使你受益非浅。

首先我们先写一个非常简单的Java源文件:

class StringTest {
    public static void main(String[] args) {
        int i = 2;
        int j = 3;
    }
}
使用Javac 命令进行编译:

javac -g StringTest.java
最终有两个文件:

user ~/csdn_test/session1$ls -l
total 16
-rw-r--r--  1 user  staff  417  4  7 21:54 StringTest.class
-rw-r--r--  1 user  staff   99  4  7 21:53 StringTest.java

以上步骤涉及到JAVA环境变量配置,不会的自己google,或者发帖询问。这里使用了-g命令,意思是生成所有调试信息。(javac -help可以查看)

下面我们分2步来看看javap的显示结果:

1.不带任何参数使用javap StringTest

【CSDN常见问题解答】Javap 的使用_第1张图片

这里我们可以看到的信息有,从哪个文件(StringTest.java)编译过来的。类里面调用两个方法,一个是默认的构造函数,一个是main方法。在没有显式声明构造方法时,会产生一个默认构造方法。这也验证了,为什么一个对象,默认总是先执行构造函数,特别是在继承的场合下,使用这个命令就可以看的很清楚了。

2.使用-c参数javap -c StringTest

【CSDN常见问题解答】Javap 的使用_第2张图片

带-p参数将额外的打印字节码信息。前面的和不带参数的输出一样,后面的显示了方法的具体的字节码,从这个输出里面我们又可以了解更多的内容。

首先是编译器生成的的缺省构造方法的内容为调用父类的构造方法super(), main()方法的字节码信息的内容这里简单解释下:

Code:
   0:   iconst_2    //把2放到栈顶
   1:   istore_1    //把栈顶的值放到局部变量1中,即i中
   2:   iconst_3    //把3放到栈顶
   3:   istore_2    //把栈顶的值放到局部变量1中,即j中
   4:   return
所以再根据开始的java源码对照,对于 int i = 2;首先它会在栈中创建一个变量为i的引用,然后查找有没有字面值为2的地址,没找到,就开辟一个存放2这个字面值的地址,然后将i指向2的地址。j也是类似的。

 延伸学习:

1、如果将main中的变量换成String 类型的,然后看看javap的结果。

比如:

String a = "a";

String b = "b";

String ab = "ab";

String ab1 = a + b;

String ab2 = "a" + "b"


2、使用更多的参数分析其结果,如javap -l xxx javap -p xxx(提示 -p会显示private相关的)

【CSDN常见问题解答】Javap 的使用_第3张图片


这几个参数几乎就可以构成javap的最常使用的集合,最常用的应该还是-c选项,因为可以打印字节码的信息,关于这些字节码的详细涵义在Java 虚拟机规范中定义,感兴趣的可以自己去找找相关资料。

你可能感兴趣的:(虚拟机,源代码,反编译,反编译工具,CSDN常见问题)