美文网首页
深入理解i++和++i

深入理解i++和++i

作者: 左眼眸子 | 来源:发表于2018-04-18 17:25 被阅读17次

看一段代码:


public static void main(String[] args){

    int i = 0;

    i = i ++;

}

i最后的结果为0,如果换成++i,i最后的结果就是1;

这个现象我相信很多人很容易解释。

1、前置++是将自身加1的值赋值给新变量,同时自身也加1。

2、后置++是将自身的值赋给新变量,然后才自身加1。

这样就结束了吗?当然不是!有没有人去证实过这个现象?JVM又是如何存储这个变量和改变这个变量的呢?

想到这里,我就开始看它的字节码文件

image

iconst_0   //把数值0推到操作数栈赋值给i

istore_1   // 把操作数栈的i值写回到局部变量第2个位置

iload_1   // 把本地变量第2个位置的值推到到操作数栈,因为要赋值给i

iinc 1, 1   // 把局部变量表第2个位置的值加1 

 istore_1   // 把操作数据栈写局部变量第2个位置

可以发现定义变量i为0是将0 push到操作数栈赋值给i,然后将i存入本地变量,下面进行i++操作的时候先从本地变量拿到i进入操作数栈,然后本地变量表的i加一,然后将赋值之后i为0的i写回本地变量。

下面看看前置++的实现:

image

不同的就是,现在本地变量表加一之后再载入数栈。

下面来普及一下java栈方面知识。

JVM中有一个数据结构叫虚拟机栈,当线程启动的时候,会分配一块内存当作该线程的栈,也就是说java是线程私有的,它的生命周期与线程相同,虚拟机栈描述的是java方法执行的内存模型:每个方法在执行的同时会创建一个栈帧用于储存局部变量、操作数栈、动态链接、方法出口等。每一个方法从调用直至执行完成的过程,就对应一个栈帧在虚拟机栈中入栈到出栈的过程。

这里重点介绍一下栈帧、局部变量和操作数栈:

栈帧:是用于支持虚拟机进行方法调用和方法执行的数据结构。对于执行引擎来说,活动线程中,只有栈顶的栈帧是有效的,称为当前栈帧,这个栈帧所关联的方法称为当前方法。执行引擎所运行的所有字节码指令都只针对当前栈帧进行操作。

局部变量:局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。在Java程序被编译成Class文件时,就在方法的Code属性的max_locals数据项中确定了该方法所需要分配的。局部变量表的容量以变量槽(Slot)为最小单位,32位虚拟机中一个Slot可以存放一个32位以内的数据类型(boolean、byte、char、short、int、float、reference和returnAddress八种)。reference类型虚拟机规范没有明确说明它的长度,但一般来说,虚拟机实现至少都应当能从此引用中直接或者间接地查找到对象在Java堆中的起始地址索引和方法区中的对象类型数据。

操作数栈:Java虚拟机的解释执行引擎被称为"基于栈的执行引擎",其中所指的栈就是指-操作数栈。操作数栈也常被称为操作栈。和局部变量区一样,操作数栈也是被组织成一个以字长为单位的数组。但是和前者不同的是,它不是通过索引来访问,而是通过标准的栈操作—压栈和出栈—来访问的。比如,如果某个指令把一个值压入到操作数栈中,稍后另一个指令就可以弹出这个值来使用。虚拟机在操作数栈中存储数据的方式和在局部变量区中是一样的:如int、long、float、double、reference和returnType的存储。对于byte、short以及char类型的值在压入到操作数栈之前,也会被转换为int。


建议:对一些自己无法理解或者解释但又想搞明白的同学,希望多去看看字节码文件。但是你打开class文件会发现是一大堆的二进制文件,到底怎么看呢?下面我就分享下如何看class的字节码文件:

image image

点击加号:

image image

温馨提示:先编译再运行哦

相关文章

  • 深入理解i++和++i

    看一段代码: i最后的结果为0,如果换成++i,i最后的结果就是1; 这个现象我相信很多人很容易解释。 1、前置+...

  • 我认为你并不理解i++和++i

    阅读原文: 你可能并不理解i++和++i 面对i++和++i,是不是经常忘记两者的区别?你是真的理解它还是只是靠死...

  • 深度理解 i++ 和 ++i

    我们都知道 i++ 与 ++i 都是自增操作。大多数也知道两种 "先加" 和 "后加的区别"。例如下方代码: 打印...

  • Java中的i++ 和 ++i 在for循环使用

    Java的i++ 和++i 的区别i++:先赋值,后计算;++i;先计算,后赋值。 for循环中的i++和++i...

  • Java 自增运算 i++ 和 ++i 的深入理解

    简单理解: i++ 是先运算后自增 ++i 是先自增后运算 虚拟机执行原理 java代码 编译后代码 jvm指令代...

  • i++和++i

    i++ 先赋值后相加 //结果65 ++i 先自加后赋值 //结果66

  • ++i和i++

    ++i和i++ 如果是自身使用,没有任何区别。 使用后再进行赋值时有区别: 前加:先自身+1再把结果赋值给...

  • i++和++i

    java场景一 打印结果: i: 0 j: 1 java场景二 打印结果: i: 0 j: 1

  • ++i和i++

    1.a = i++; 等校为 a = i; i = i + 1; 2.a = ++i; 等校为 i = i ...

  • i++和++i的区别

    i++和++i有哪些区别? i++和++i都是实现变量i的自增,两者的区别在于i++是先运算,再加1,而++i是先...

网友评论

      本文标题:深入理解i++和++i

      本文链接:https://www.haomeiwen.com/subject/jchbkftx.html