看一些JAVA基础题的时候,经常看到这个问题,很多人的解释是:i++最快,i+=1其次,i=i+1最慢。下面通过Sun JDK编译出来的字节码验证一下这个问题。

为了让编译出来的字节码便于阅读,将这三个表达式分别写在一个方法里面:

     private void a(){
int i=0;
i += 1;
} private void b(){
int i=0;
i++;
} private void c(){
int i=0;
i=i+1;
}

编译之后(SUN JDK1.7),再看编译出来的字节码(直接把.class文件用IDE打开,或者用javap -v -p classFileName命令):

// Method descriptor #6 ()V
// Stack: 1, Locals: 2
private void a();
0 iconst_0
1 istore_1 [i]
2 iinc 1 1 [i]
5 return
Line numbers:
[pc: 0, line: 15]
[pc: 2, line: 16]
[pc: 5, line: 17]
Local variable table:
[pc: 0, pc: 6] local: this index: 0 type: com.leo.javabasis.Add
[pc: 2, pc: 6] local: i index: 1 type: int // Method descriptor #6 ()V
// Stack: 1, Locals: 2
private void b();
0 iconst_0
1 istore_1 [i]
2 iinc 1 1 [i]
5 return
Line numbers:
[pc: 0, line: 20]
[pc: 2, line: 21]
[pc: 5, line: 22]
Local variable table:
[pc: 0, pc: 6] local: this index: 0 type: com.leo.javabasis.Add
[pc: 2, pc: 6] local: i index: 1 type: int // Method descriptor #6 ()V
// Stack: 1, Locals: 2
private void c();
0 iconst_0
1 istore_1 [i]
2 iinc 1 1 [i]
5 return
Line numbers:
[pc: 0, line: 25]
[pc: 2, line: 26]
[pc: 5, line: 27]
Local variable table:
[pc: 0, pc: 6] local: this index: 0 type: com.leo.javabasis.Add
[pc: 2, pc: 6] local: i index: 1 type: int

这三个方法的字节码是一样的(除了行号),先稍微解释一下这段字节码指令:

iconst_0 //整数常量0入栈
istore_1 //将栈上的值出栈,保存到序号为1的局部变量(也就是i)
iinc 1 1 //将序号为1的局部变量增加1,此指令语法为iinc index const。
是不是SUN JDK在某一个版本之前是没有对这个问题进行优化?找了一个能用的SUN JDK 1.3再试了一下(1.1, 1.2跑不动了),编译出来的结果,方法a、b的字节码和1.7下是一样的。但是c的就不一样了:
Method void c()
0 iconst_0
1 istore_1
2 iload_1
3 iconst_1
4 iadd
5 istore_1
6 return

指令行2-5的作用分别是:

iload_1 //将序号为1的局部整数变量入栈
iconst_1 //整数常量1入栈
iadd //使用栈上的两个整数值出栈进行加法运算,将结果入栈
istore_1 //将栈上的整数值保存到序号为1的局部变量
这种方式同样达到了相加的目的,但是相比直接iinc指令,还是绕了很多,效率自然不会好。

由此看来,在某一个版本之后,编译器是对这个问题进行了优化。关于谁的效率好的问题,在现在的SUN JDK版本中已经没有差别了(即使是使用1.7的JDK编译出的1.3JRE兼容的字节码,方法c也是优化过的),
但是曾经某个时代确实是有差别的。

JAVA的i++, i+=1, i=i+1有区别吗?的更多相关文章

  1. Java中集合List,Map和Set的区别

    Java中集合List,Map和Set的区别 1.List和Set的父接口是Collection,而Map不是 2.List中的元素是有序的,可以重复的 3.Map是Key-Value映射关系,且Ke ...

  2. Java中的“==操作符”和equals方法有什么区别

    Java中的"=="和equals方法究竟有什么区别? 1.==操作符 "=="操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的 ...

  3. 列举两种不同类型的Java标识注释,并解释它们之间的区别。

    列举两种不同类型的Java标识注释,并解释它们之间的区别.

  4. java多线程之yield,join,wait,sleep的区别

    Java多线程之yield,join,wait,sleep的区别 Java多线程中,经常会遇到yield,join,wait和sleep方法.容易混淆他们的功能及作用.自己仔细研究了下,他们主要的区别 ...

  5. JAVA基础2---深度解析A++和++A的区别

    我们都知道JAVA中A++和++A在用法上的区别,都是自增,A++是先取值再自增,++A是先自增再取值,那么为什么会是这样的呢? 1.关于A++和++A的区别,下面的来看个例子: public cla ...

  6. Java Web开发和Python Web开发之间的区别

    今天的文章讨论了Java Web开发和Python Web开发之间的区别.我不鼓励我们在这里从Java Web迁移到Python Web开发.我只是想谈谈我的感受.它不一定适合所有情况,仅供我们参考. ...

  7. 杂项-Java:jar 包与 war 包介绍与区别

    ylbtech-杂项-Java:jar 包与 war 包介绍与区别 1.返回顶部 1. 做Java开发,jar包和war包接触的挺多的,有必要对它们做一个深入的了解,特总结整理如下: 1.jar包的介 ...

  8. “全栈2019”Java第一百一十章:局部内部类与匿名内部类区别详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  9. [转]Java五个最常用的集合类之间的区别和联系

    Map<String, ?>只能是只读模式,不能增加,因为增加的时候不知道该写入什么类型的值:Map<String, Object>可以读和写,只要是所有Object类的子类都 ...

  10. java中,return和return null有什么区别吗?

    java中,return和return null有什么区别吗? 最大的区别:return;方法的返回值必须是void!return null;方法的返回值必须不是 原始数据类型(封装类除过)和void ...

随机推荐

  1. BZOJ1500: [NOI2005]维修数列[splay ***]

    1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 12278  Solved: 3880[Submit][Statu ...

  2. POJ1740A New Stone Game[组合游戏]

    A New Stone Game Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5769   Accepted: 3158 ...

  3. JSLint检测Javascript语法规范

    前端javascript代码编写中,有一个不错的工具叫JSLint,可以检查代码规范化,压缩JS,CSS等,但是他的语法规范检查个人觉得太“苛刻”了,会提示各种各样的问题修改建议,有时候提示的信息我们 ...

  4. java多线程系类:JUC线程池:02之线程池原理(一)

    在上一章"Java多线程系列--"JUC线程池"01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我 ...

  5. 12款经典的白富美型—jquery图片轮播插件—前端开发必备

    图片轮播是网站中的常用功能,用于在有限的网页空间内展示一组产品图片或者照片,同时还有非常吸引人的动画效果.本文向大家推荐12款实用的 jQuery 图片轮播效果插件,帮助你在你的项目中加入一些效果精美 ...

  6. Elasticssearch学习教程

    http://www.cnblogs.com/eggTwo/p/4425269.html

  7. c#如何实现一个线程暂停,等待用户输入文本后继续运行?

    using System; using System.Text; using System.Windows.Forms; using System.Threading; namespace Windo ...

  8. 个人作业——关于K米的产品案例分析

    Notice:本文所采用的K米版本为 Version:4.3.0 Release:20161014 第一部分 调研,评测 评测: 软件的bug,功能评测,黑箱测试 1.下载并使用,描述最简单直观的个人 ...

  9. 重写navigationController的push方法后,出现卡顿现象

    在使用navigation的pushViewController进行push的时候,两个页面间的动画会出现卡顿一下再推出的效果,是因为iOS7 viewController背景颜色的问题,看到大神的博 ...

  10. python 批量扫描mongodb 未授权访问脚本

    需要 pymongo库easy_install pymongo脚本: import socket import sys import pymongo ipcons = [] def Scanner(i ...