Java中 i=i++ 问题底层原理解析

有如下代码:

public class Main {
    public static void main(String[] args) {
        int i = 10;
        i = i++;
        System.out.println(i);
    }
}

运行后,发现结果为10,而不是11。这是为什么呢?

首先先介绍一个JDK自带的反编译工具: javap命令。 可以看到到底底层是怎么执行上面的代码的!

先编译Main.java文件

C:\leetcode\src\com\lilike>javac Main.java

此时在Main.java 目录下生成了Main.class文件。
然后执行javap命令:

C:\leetcode\src\com\lilike>javap -c Main
警告: 二进制文件Main包含com.lilike.Main
Compiled from "Main.java"
public class com.lilike.Main {
  public com.lilike.Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: bipush        10
       2: istore_1
       3: iload_1
       4: iinc          1, 1
       7: istore_1
       8: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      11: iload_1
      12: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
      15: return
}

上面的0,2,3,4,7操作,就是底层i = i ++的执行过程,我们先解释这五项操作,在文章的末尾再补充虚拟机指令的知识。

0: bipush        10  //将参数10压入栈
2:istore_1     //栈中弹出一个数(10),赋值给局部变量i(_1表示赋值给第一个局部变量,即i)
3: iload_1  //将局部变量i(_1表示第一个局部变量,即i)的值入栈,此时栈顶的值为10
4: iinc     1, 1  //指令iinc对给定的局部变量做自增操作
//1,1表示对第一个局部变量i进行累加1操作,意味着i变为了11
7: istore_1   //栈顶弹出一个数:也就是10,赋值给第一个局部变量i。意味着i的值又变回10了。(_1表示赋值给第一个局部变量,即i)

最终打印结果 就是: 10

扩充知识-- java虚拟机指令:
bipush:当int取值-128~127时,JVM采用bipush指令将常量压入栈中。
istore:将栈顶int型数值存入指定本地变量
aload:从局部变量表的相应位置装载一个对象引用到操作数栈的栈顶。还有一些其他相似的操作码用来装载非对象引用,包括iload_、lload_、fload_和dload_,这里的i代表int型,l代表long型,f代表float型以及d代表double型。
iinc:变量自增。

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值