zoukankan      html  css  js  c++  java
  • Java深入学习17:从字节码指令角度理解i++和++i

    Java深入学习17:从字节码指令角度理解i++和++i

    一、先看一段代码

    public class AutoIncrementTest {
    
        public static void main(String[] args) {
            int i =  1;
            i = i++;
            int j = i++;
            int k = i + ++i * i++;
            System.out.println("i = " + i);//i = 4
            System.out.println("j = " + j);//j = 1
            System.out.println("k = " + k);//k = 11 (2 + 3 * 3)
        }
    
    }

    二、从字节码指令角度理解i++和++i

            //i++ 和 ++i 的区别,从字节码指令角度,
            //比如int a = b;逻辑是,将局部变量b的值入栈,将入栈的值赋给a;
            //那么 int a = b++,表示局部变量b值先入栈,再b本身自增(但不影响入栈的b值),将入栈的值赋给a;
            //那么 int a = ++b,表示局部变量b值本身先自增,自增后的b值入栈,将入栈的值赋给a;

    三、代码字节码解释

        public class interview.AutoIncrementTest {
      public interview.AutoIncrementTest();
            Code:
            0: aload_0
            1: invokespecial #1                  // Method java/lang/Object."<init>":()V
            4: return
    
            public static void main(java.lang.String[]);
            Code:
    
            // int i = 1
            0: iconst_1     // 1(int)值入栈
            1: istore_1     // 将栈顶int类型值保存到局部变量1中
    
            //i = i++
            2: iload_1      //从局部变量1中装载int类型值入栈。
            3: iinc          1, 1       //将整数值constbyte加到indexbyte指定的int类型的局部变量中(1,1表示1加到变量1中)
            6: istore_1     //将栈顶int类型值保存到局部变量1中
    
            //int j = i++;
            7: iload_1      //从局部变量1中装载int类型值入栈
            8: iinc          1, 1       //将整数值constbyte加到indexbyte指定的int类型的局部变量中(1,1表示1加到变量1中)
            11: istore_2    //将栈顶int类型值保存到局部变量2中
    
            int k = i + ++i * i++;
            //i
            12: iload_1     //从局部变量1中装载int类型值入栈
            //++i
            13: iinc          1, 1       //将整数值constbyte加到indexbyte指定的int类型的局部变量中(1,1表示1加到变量1中)
            16: iload_1     //从局部变量1中装载int类型值入栈
            //i++
            17: iload_1     //从局部变量1中装载int类型值入栈
            18: iinc          1, 1       //将整数值constbyte加到indexbyte指定的int类型的局部变量中(1,1表示1加到变量1中)
            21: imul        //将栈顶两int类型数相乘,结果入栈
            22: iadd        //将栈顶两int类型数相加,结果入栈
            23: istore_3        //将栈顶int类型值保存到局部变量3中
    
            //以下略
            24: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
            27: new           #3                  // class java/lang/StringBuilder
            30: dup
            31: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
            34: ldc           #5                  // String i =
            36: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
            39: iload_1
            40: invokevirtual #7                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
            43: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
            46: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            49: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
            52: new           #3                  // class java/lang/StringBuilder
            55: dup
            56: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
            59: ldc           #10                 // String j =
            61: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
            64: iload_2
            65: invokevirtual #7                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
            68: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
            71: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            74: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
            77: new           #3                  // class java/lang/StringBuilder
            80: dup
            81: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
            84: ldc           #11                 // String k =
            86: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
            89: iload_3
            90: invokevirtual #7                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
            93: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
            96: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            99: return
        }

    四、附: IDE使用javap查看字节码,文章参考:https://blog.csdn.net/qq_41618510/article/details/84669443

    主要设置如下

    END

  • 相关阅读:
    解决GitHub下载速度缓慢的问题
    什么是“个人商业模式”?就是一个人出售自己时间的方式
    phpstudy如何安装ssl证书
    心不动——王阳明最可怕之处
    人间立命王阳明
    计算机视觉数据集
    ECG心电图数据2
    ECG心电图数据1
    梯度下降VS随机梯度下降
    SGD
  • 原文地址:https://www.cnblogs.com/wobuchifanqie/p/12604980.html
Copyright © 2011-2022 走看看