一个简单的例子教会您使用javap

发布时间:2019-11-19 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了一个简单的例子教会您使用javap脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

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();     } }@H_83_126@

使用下面的命令行对NullableTest进行反编译,以java编译器生成的字节码:

javap -v NullableTest >c:code1.txt

查看方法way1()对应的字节码:

一个简单的例子教会您使用javap

下面这个wiki包含了java字节码里每个指令的具体说明:

https://en.wikipedia.org/wiki...

一个简单的例子教会您使用javap

面对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行字节码,即直接返回。

一个简单的例子教会您使用javap

如果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

javap生成的字节码里的LineNumberTable也很有用。这张表里每行的line后面的数字代表Java源代码的序号,line XX冒号后面的数字代表字节码里每行指令的序号。看看下图中Java源代码和对应的字节指令在LineNumberTable中的映射关系。

一个简单的例子教会您使用javap

LineNumberTable维护了Java源代码同字节指令的映射关系,确保了Java代码调试的顺利进行。

一个简单的例子教会您使用javap

要获取更多Jerry的原创文章,请关注公众号"汪子熙"或者扫描下面二维码:

一个简单的例子教会您使用javap

一个简单的例子教会您使用javap

脚本宝典总结

以上是脚本宝典为你收集整理的一个简单的例子教会您使用javap全部内容,希望文章能够帮你解决一个简单的例子教会您使用javap所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。