关于的Java的i++和++i的区别,初学者可能会混淆,这时候有经验的同学或同事就会告诉你,++在后,就会立马加值,

++在后则会等会儿再加,所以如果i == 0 ,那么i++ == 0,++i == 1。

  那么这个先加后加具体在字节码中是怎样一个逻辑呢?这个就需要我们去看看Java的字节码了,如何查看字节码请

参考我之前的文章IDEA设置External Tools之Javap反编译字节码

  准备两个函数

  函数test1

  

  函数test2

  

  先直接上函数的打印结果就,再来慢慢分析

  

  先看test1的字节码

  

  0~3行:一次定义了i和j两个变量,并赋值为0,存放在局部变量表。

  4~7行:开始循环的逻辑,if_icmpge是比较语句,如果j>=50则直接跳到第21行,调用打印方法。

  核心的逻辑在10~15行:

  

  现将局部变量表slot 0的变量加载到操作数栈,接着对局部变量表自增(没错,你没看错,这里是对局部

变量表自增而不是对操作数栈的变量自增)。。紧接着下一步istore_0又把栈顶的值存回局部变量表slot_0,所以,。。

最终局部变量表的值是没有改变的。

  i++分析完毕,再回看上面的字节码,其中还有值得注意的地方:

  

  21~43行:这段对应代码

1 System.out.println("i++: " + i);

  先new一个PrintStream对象,下面可以看到是new了一个StringBuilder对象。这里可能是jvm的一个优化,将字符串拼接

改成了StringBuilder来append,所以我们经常看到的有人说要把字符串拼接改成StringBuilder其实大可不必,先看下字节码

对于语句的优化是怎样的。

  接着来看test2方法的字节码:

  前面的代码和test1一样,我们直接来看不一样的地方:

  

  该段字节码对应代码:

i = ++i;

  先对局部变量表上的值自增,再加到操作数栈,最终存回到局部变量表,这样的话变量表的值就是实实在在

增加了的。

  所以,回想上面的分析,得出结论就是:i++是将变量表的值加载操作数栈后再对变量表上的值自增,而++i

则是先对变量表上的值自增后再将其加载到操作数栈。

  当然,殊途同归,最终不管是i++还是++i,都是为了自增。

  ~~本文结束,感谢各位看官。

  

从字节码层次看i++和++i的更多相关文章

  1. 从字节码层面看“HelloWorld” (转)

    一.HelloWorld 字节码生成 众所周知,Java 程序是在 JVM 上运行的,不过 JVM 运行的其实不是 Java 语言本身,而是 Java 程序编译成的字节码文件.可能一开始 JVM 是为 ...

  2. 从字节码层面看“HelloWorld”

    一.HelloWorld 字节码生成 众所周知,Java 程序是在 JVM 上运行的,不过 JVM 运行的其实不是 Java 语言本身,而是 Java 程序编译成的字节码文件.可能一开始 JVM 是为 ...

  3. 从字节码指令看重写在JVM中的实现

    Java是解释执行的.包含动态链接的特性.都给解析或执行期间提供了非常多灵活扩展的空间.面向对象语言的继承.封装和多态的特性,在JVM中是怎样进行编译.解析,以及通过字节码指令怎样确定方法调用的版本号 ...

  4. 从java字节码角度看线程安全性问题

    先看代码: package com.roocon.thread.t3; public class Sequence { private int value; public int getNext(){ ...

  5. 从jvm字节码指令看i=i++和i=++i的区别

    1. 场景的产生 先来看下下面代码展示的两个场景 @Testvoid testIPP() { int i = 0; for (int j = 0; j < 10; j++) { i = i++; ...

  6. i++ 与 ++i 的从字节码层面看二者的区别

    /** * javap命令可以对class反汇编得到其字节码文件(此命令并不是jdk8开始的,只不过jdk8中对工具进行加强,增加了一些参数,可通过 javap -help了解) * * 注意: * ...

  7. 从JVM字节码执行看重载和重写

    Java 重写(Override)与重载(Overload) 重写(Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变.即外壳不变,核心重写! 重写的 ...

  8. java中i=i++字节码分析

    原文出处: Ticmy 1 2 int i = 0; i = i++; 结果还是0为什么? 程序的执行顺序是这样的:因为++在后面,所以先使用i,"使用"的含义就是i++这个表达式 ...

  9. 《深入理解Java虚拟机》-----第8章 虚拟机字节码执行引擎——Java高级开发必须懂的

    概述 执行引擎是Java虚拟机最核心的组成部分之一.“虚拟机”是一个相对于“物理机”的概念 ,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器.硬件.指令集和操作系统层面上的,而 ...

随机推荐

  1. bootstrap的时间控件使用(双日历)

    这段时间看了下bootstrap的时间控件,发现使用起来还是很简单的,趁着有时间的时候整理了一下,方便自己以后忘记的时候查阅... 废话不多说先上效果图 接下来是代码实现 第一步当然是导入css.js ...

  2. CodeForces - 1114D-Flood Fill (区间dp)

    You are given a line of nn colored squares in a row, numbered from 11 to nn from left to right. The  ...

  3. iptables实用知识 ,一文学会配置linux防火墙

    目录 1.防火墙的概念 2. linux防火墙 3.linux数据包处理流程 3.1 linux 防火墙将以上流程,固定区分为5个流程节点 3.2 数据流程 4 linux防火墙的实现机制 4.1 i ...

  4. webapi上传图片的两种方式

    /// <summary>        /// App上传图片        /// </summary>        /// <returns>返回上传图片的 ...

  5. css3渐变色实现小功能 ------ css(linaer-gradient)

    由沿直线两种或多种颜色之间的渐进转换的图像.它的结果是数据类型的对象,这是一种特殊的类型. 与任何梯度一样,线性梯度没有内在维度 ; 即,它没有天然或优选的尺寸,也没有优选的比例.其具体尺寸将与其适用 ...

  6. pwnable.kr之bof

    打开题目: 先下载题目给我们的两个文件,查看文件信息: 发现没有执行的权限,所以先增加文件bof的执行权限,执行: 没发现啥,然后查看代码, #include <stdio.h> #inc ...

  7. CSS特效(一)

    三角形 <!-- log --> <div class="tri"></div> <style> .tri { width: 0; ...

  8. 分布式事务框架.NetCore CAP总结

    来自CAP原作者yang-xiaodong的原理图: 本文撰写者:cmliu,部分内容引用自官方文档,部分内容待更新# .NetCore CAP # 1,简介 CAP 是一个遵循 .NET Stand ...

  9. PHP相关的书签内容

    ThinkPHP函数详解 session方法 --ThinkPHP 开源PHP框架 ThinkPHP实现支付宝接口功能 - /折磨 - 博客园 php几个常用的概率算法(抽奖.广告首选) - 懒人技术 ...

  10. [LeetCode]347. 前 K 个高频元素(堆)

    题目 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1 ...