一个理解JVM的例子2

新建一个Java程序: "LocalDemo.java"

 import java.util.*;
 public class LocalDemo {
 
     private List<String> data = new ArrayList<>();
 
     public void someMethod(String param) {
         List<String> data = this.data;
         if (data != null && data.size() > 0 && data.contains(param)) {
             System.out.println(data.indexOf(param));
        }
 
    }
 
 }

使用javac编译

 javac LocalDemo.java

编译后生成class文件: "LocalDemo.class"

(生成的class文件实际就是Java bytecode)

使用javap反汇编class文件

 javap -c LocalDemo

反汇编结果:

 Compiled from "LocalDemo.java"
 public class LocalDemo {
  public LocalDemo();
    Code:
        0: aload_0
        1: invokespecial #1                 // Method java/lang/Object."<init>":()V
        4: aload_0
        5: new           #2                 // class java/util/ArrayList
        8: dup
        9: invokespecial #3                 // Method java/util/ArrayList."<init>":()V
       12: putfield      #4                 // Field data:Ljava/util/List;
       15: return
 
  public void someMethod(java.lang.String);
    Code:
        0: aload_0
        1: getfield      #4                 // Field data:Ljava/util/List;
        4: astore_2
        5: aload_2
        6: ifnull        41
        9: aload_2
       10: invokeinterface #5, 1           // InterfaceMethod java/util/List.size:()I
       15: ifle          41
       18: aload_2
       19: aload_1
       20: invokeinterface #6, 2           // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
       25: ifeq          41
       28: getstatic     #7                 // Field java/lang/System.out:Ljava/io/PrintStream;
       31: aload_2
       32: aload_1
       33: invokeinterface #8, 2           // InterfaceMethod java/util/List.indexOf:(Ljava/lang/Object;)I
       38: invokevirtual #9                 // Method java/io/PrintStream.println:(I)V
       41: return
 }

结果分析

 Compiled from "LocalDemo.java"
 public class LocalDemo {
  public LocalDemo();
    Code:
        0: aload_0
        1: invokespecial #1                 // Method java/lang/Object."<init>":()V
        4: aload_0
        5: new           #2                 // class java/util/ArrayList
        8: dup
        9: invokespecial #3                 // Method java/util/ArrayList."<init>":()V
       12: putfield      #4                 // Field data:Ljava/util/List;
       15: return
 
  public void someMethod(java.lang.String);
    Code:
        0: aload_0
        1: getfield      #4                 // Field data:Ljava/util/List;
        4: astore_2
        5: aload_2
        6: ifnull        41
        9: aload_2
       10: invokeinterface #5, 1           // InterfaceMethod java/util/List.size:()I
       15: ifle          41
       18: aload_2
       19: aload_1
       20: invokeinterface #6, 2           // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
       25: ifeq          41
       28: getstatic     #7                 // Field java/lang/System.out:Ljava/io/PrintStream;
       31: aload_2
       32: aload_1
       33: invokeinterface #8, 2           // InterfaceMethod java/util/List.indexOf:(Ljava/lang/Object;)I
       38: invokevirtual #9                 // Method java/io/PrintStream.println:(I)V
       41: return
 }

修改Java程序:LocalDemo.java

 import java.util.*;
 public class LocalDemo {
 
     private List<String> data = new ArrayList<>();
 
     public void someMethod(String param) {
         //List<String> data = this.data;
         if (data != null && data.size() > 0 && data.contains(param)) {
             System.out.println(data.indexOf(param));
        }
 
    }
 
 }

再次编译和反汇编结果如下

 Compiled from "LocalDemo.java"
 public class LocalDemo {
  public LocalDemo();
    Code:
        0: aload_0
        1: invokespecial #1                 // Method java/lang/Object."<init>":()V
        4: aload_0
        5: new           #2                 // class java/util/ArrayList
        8: dup
        9: invokespecial #3                 // Method java/util/ArrayList."<init>":()V
       12: putfield      #4                 // Field data:Ljava/util/List;
       15: return
 
  public void someMethod(java.lang.String);
    Code:
        0: aload_0
        1: getfield      #4                 // Field data:Ljava/util/List;
        #getfield 表示获取对象的成员变量值(在这里的成员变量是data)
        4: ifnull        48
        7: aload_0
        8: getfield      #4                 // Field data:Ljava/util/List;
       11: invokeinterface #5, 1           // InterfaceMethod java/util/List.size:()I
       16: ifle          48
       19: aload_0
       20: getfield      #4                 // Field data:Ljava/util/List;
       23: aload_1
       24: invokeinterface #6, 2           // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
       29: ifeq          48
       32: getstatic     #7                 // Field java/lang/System.out:Ljava/io/PrintStream;
       35: aload_0
       36: getfield      #4                 // Field data:Ljava/util/List;
       39: aload_1
       40: invokeinterface #8, 2           // InterfaceMethod java/util/List.indexOf:(Ljava/lang/Object;)I
       45: invokevirtual #9                 // Method java/io/PrintStream.println:(I)V
       48: return
 }

对比修改前后的结果,发现指令"getfield"出现的次数大增(前1次,后4次!)

posted @ 2020-03-30 09:54  海纳分享  阅读(161)  评论(0编辑  收藏  举报