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

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

image.png

这篇文章使用下面这段简单的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();
  }
}

image.png

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

image.png

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

image.png


相关文章
|
2月前
|
Java 关系型数据库 MySQL
分享50个Java源码总有一个是你想要的
分享50个Java源码总有一个是你想要的
40 6
|
3月前
|
设计模式 Java 程序员
优雅整洁的 Java 代码命名技巧,风之极·净化
优雅整洁的 Java 代码命名技巧,风之极·净化
107 0
|
3月前
|
监控 JavaScript 安全
分享70个Java源码总有一个是你想要的
分享70个Java源码总有一个是你想要的
60 0
分享70个Java源码总有一个是你想要的
|
3月前
|
新零售 移动开发 JavaScript
分享74个Java源代码总有一个是你想要的
分享74个Java源代码总有一个是你想要的
19 0
|
8月前
|
存储 安全 Java
Java-反射(有图有例子,清晰易懂)
反射:框架设计的灵魂 1、概念 Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。
Java-反射(有图有例子,清晰易懂)
|
9月前
|
C++
【C++】如何写一个C++类?
【C++】如何写一个C++类?
57 0
|
Python Windows
你真的看得懂报错吗?
你真的看得懂报错吗?
274 0
你真的看得懂报错吗?
|
设计模式 存储 Java
14 个写 Java 代码的好习惯,写得太好了...
14 个写 Java 代码的好习惯,写得太好了...
132 0
14 个写 Java 代码的好习惯,写得太好了...
|
存储 自然语言处理 IDE
Java 编译期与运行期,别傻傻分不清楚!
不知大家有没有思考过,当我们使用IDE写了一个Demo类,并执行main函数打印 hello world时都经历了哪些流程么? 想通过这篇文章来分析分析Java的执行流程,或者换句话说想聊聊Java的编译期与运行期的流程。
Java 编译期与运行期,别傻傻分不清楚!
|
存储 Java 编译器
我要悄悄学习 Java 字节码指令,在成为技术大佬的路上一去不复返(1)
我要悄悄学习 Java 字节码指令,在成为技术大佬的路上一去不复返
115 0
我要悄悄学习 Java 字节码指令,在成为技术大佬的路上一去不复返(1)