重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇文章给大家分享的是有关如何使用javap的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
创新互联坚信:善待客户,将会成为终身客户。我们能坚持多年,是因为我们一直可值得信赖。我们从不忽悠初访客户,我们用心做好本职工作,不忘初心,方得始终。十多年网站建设经验创新互联是成都老牌网站营销服务商,为您提供网站制作、成都网站建设、网站设计、H5开发、网站制作、高端网站设计、微信平台小程序开发服务,给众多知名企业提供过好品质的建站服务。
javap是JDK自带的工具:
这篇文章使用下面这段简单的Java代码作为例子进行讲解。
class Outer { Nested nested; Nested getNested() { return nested; } }class Nested { Inner inner; Inner getInner() { return inner; } }class Inner { String foo; String getFoo() { return foo; } }public class NullableTest { public static Outer getInitializedOuter(){ Outer outer = new Outer(); outer.nested = new Nested(); outer.nested.inner = new Inner(); outer.nested.inner.foo = "Jerry"; return outer; } /* null pointer exception private static void way0(){ Outer outer = new Outer(); System.out.println(outer.nested.inner.foo); }*/ public static void way1(){ Outer outer = getInitializedOuter(); if (outer != null && outer.nested != null && outer.nested.inner != null) { System.out.println(outer.nested.inner.foo); } } public static void main(String[] args) { //way0(); way1(); } }
使用下面的命令行对NullableTest进行反编译,以java编译器生成的字节码:
javap -v NullableTest >c:\code\1.txt
查看方法way1()对应的字节码:
下面这个wiki包含了java字节码里每个指令的具体说明:
https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
下面对NullableTest反编译得到的字节码做一些说明:
0: invokestatic #42 // Method getInitializedOuter:()Ljava8/Outer;
代表静态方法getInitializedOuter的调用, Ljava8/Outer意思是该方法的返回类型是Outer
3: astore_0
将上述静态方法调用返回的outer引用存储到局部变量中,局部变量的id为0.
4: aload_0
因为在我前面的Java源代码中,我将静态方法返回的对象引用同null做了比较,因此使用指令aload_0将存储在代号为0的局部变量中的对象引用重新加载到栈上,此后才能和null做比较。
5: ifnull 41
这就是我在Java源代码里书写的IF分支。如果IF分支里检测的outer引用为null,则直接返回了。体现在字节码就是,如果ifnull为true,则跳转到第41行字节码,即直接返回。
如果ifnull不为true,则继续执行下去。又将outer引用加载到栈上。
从字节码的分析可以观察到一个有趣的现象,再次看看我们的IF语句。
Java编译时,编译器实际将其转换成了下面的写法:
if (outer == null )return;if( outer.nested == null )return;if( outer.nested.inner == null)return; System.out.println(outer.nested.inner.foo);
这个事实可以通过下图得到确认。
javap生成的字节码里的LineNumberTable也很有用。这张表里每行的line后面的数字代表Java源代码的序号,line XX冒号后面的数字代表字节码里每行指令的序号。看看下图中Java源代码和对应的字节指令在LineNumberTable中的映射关系。
LineNumberTable维护了Java源代码同字节指令的映射关系,确保了Java代码调试的顺利进行。
感谢各位的阅读!关于“如何使用javap”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!