专栏首页Jerry的SAP技术分享一个简单的例子教会您使用javap

一个简单的例子教会您使用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();
    }
}

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

javap -v NullableTest >c:\code\1.txt

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

下面对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代码调试的顺利进行。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

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

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

    Jerry Wang
  • Chrome开发者工具中Elements(元素)断点的用途

    SAP Engagement Center UI的这个按钮会每秒钟刷新一次,显示页面已经打开了多长时间。

    Jerry Wang
  • JDBC + SAP云平台 = 运行在云端的数据库应用

    在前一篇文章JPA + EclipseLink + SAP云平台 = 运行在云端的数据库应用我介绍了如何通过JPA和EclipseLink操作部署在SAP云平台...

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

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

    Jerry Wang
  • python之string模块的find

    解释:str:被查找“字串”(气味字符串的函数);pos_start:查找的首字母位置(从0开始计数。默认:0);pos_end:查找的末 尾位置(不包括末尾位...

    py3study
  • Python3通过JDBC访问非Kerberos环境的Impala

    在前面Fayson介绍了在Python2的环境下《如何使用Python Impyla客户端连接Hive和Impala》及《Python3环境通过JDBC访问非K...

    Fayson
  • Python3环境通过JDBC访问非Kerberos环境的Hive

    在前面Fayson介绍了在Python2的环境下《如何使用Python Impyla客户端连接Hive和Impala》,本篇文章Fayson主要介绍在Pytho...

    Fayson
  • 微信小程序日常踩坑后的总结(猜测你也会遇到,持续更新。。。)

    (1)图片需是本地图片或者是路径为https的网络图片; (2)使用网络图片要用wx.downloadFile( )下载,否则真机上无法显示图片; (3)w...

    Ewall
  • 高斯消去法解方程组及Python实现

    Python 是一种高级计算机程序设计语言。对于初学者和完成普通任务, Python 语言是非常简单易用的。 对于方程组Ax=b,增广矩阵为[A b]。第一次消...

    fem178
  • React Native 新架构

    原文:https://github.com/xiaoxiaosaohuo/Note/issues/60

    ConardLi

扫码关注云+社区

领取腾讯云代金券