专栏首页光变Java中关于i=i++的问题解些

Java中关于i=i++的问题解些

本文在JVM指令层次讲解i=i++之后,i的值不变的问题。.

背景知识

JVM在方法体中的操作指令,一部分是直接作用stack栈,也有一些部分是直接操作Local Variable(本地变量区/局部变量区)。

简单的介绍两个指令

ILOAD

将一个整数常量push到方法栈中。

ILOAD n 执行前stack

index

value

0

1

ILOAD n 执行后stack

index

value

0

1

n

而本地变量区没有变化。

ISTORE

将一个整数常量pop出方法栈,并将该常量值赋值给本地变量区(Local Variable)。

ISTORE n 执行前stack

index

value

0

1

x

ISTORE n 执行后stack

index

value

0

1

ISTORE n 执行前 Local Variable

index

value

0

n

ISTORE n 执行后Local Variable

index

value

0

n

x

IINC

将一个本地变量区(Local Variable)的整数常量值加1。

本地方法栈无变化。

ISTORE n 执行前 Local Variable

index

value

0

n

x

ISTORE n 执行后Local Variable

index

value

0

n

x + 1

i++ VS ++i

在平时的讲解中,”i++“ 这条指定会在完成整个语句运算后执行,”++i“ 这条指令会在整个语句运算前执行。

实例讲解

i=i++

现在有一段代码如下

public void afterPlus() {
    int i = 0;
    i = i++;
    Assert.assertEquals(0, i);
}

编译成指令后,其中i=i++的指令如下

ILOAD 1
IINC 1 1
ISTORE 1

应该有部分同学明白了,ILOAD指令先把i的原始值先被加载到了stack中, 然后IINC指令将本地变量中的i进行了+1操作,但是栈上的i还是原始值。 然后ISTORE指令又将栈上的i的原始变量值付给了本地变量i。 所以i相当于没做操作。

i=++i

代码如下

public void beforePlus() {
    int i = 0;
    i = ++i;
    Assert.assertEquals(1, i);
}
}

编译成指令后,其中i=i++的指令如下

IINC 1 1
ILOAD 1
ISTORE 1

IINC指令将本地变量中的i进行了+1操作, ILOAD指令先把i+1的值先被加载到了stack中, ISTORE指令stack上的新值赋值付给了本地变量i, 所以本地变量是+1后的值。

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 3.1 ASM-方法-结构

    ASM-方法-结构 本章将会介绍如果使用ASM core API生成或者转换Java编译后的method。 本将开始会展示编译后的method,然后使用很多说...

    白凡
  • Java使用slf4j输出日志

    白凡
  • Spring PlaceHolder使用注意事项

    对Spring Property Placeholder如何使用,以及使用过程中遇到的问题做了简单的描述。

    白凡
  • python - 字典

    *********************字典******************

    py3study
  • (五)c#Winform自定义控件-复选框

    GitHub:https://github.com/kwwwvagaa/NetWinformControl

    冰封一夏
  • 一个HTTP数据包的奇幻之旅

    “还能去哪里,你是一个数据包,当然要出远门,完成你的使命啊,别啰嗦,我要先把你复制到内核空间,一会要发出去,让我来看下你的内容”。

    lucifer210
  • 填坑唯品会分布式调度Saturn

    但其实node.js 8.7.0就已经包含了npm 5.4.2,首先下载node.js 8.7.0

    算法之名
  • 基于 localStorage 实现一个具有过期时间的 DAO 库

    我们将基于localStorage原始api进行扩展,让其支持失效时间,操作完成后的回调。在文章的最后,我将给出库的完成代码,接下来我们就一步步实现吧。

    徐小夕
  • Android开发工具之ParcelUtils和SerializeUtils

    今天我们来讲的这两个工具类是在Activity之间跳转时常常要传递的和对象序列化什么有关的。那么接下来,我们来看看吧! SerializeUtils 包含一...

    非著名程序员
  • 033android初级篇之android的Observer模式

    android中的Observer模式,是继承自java的实现,使用Observable类和Observer实现。

    上善若水.夏

扫码关注云+社区

领取腾讯云代金券