JAVA的i++, i+=1, i=i+1有区别吗?
看一些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有区别吗?的更多相关文章
- Java中集合List,Map和Set的区别
Java中集合List,Map和Set的区别 1.List和Set的父接口是Collection,而Map不是 2.List中的元素是有序的,可以重复的 3.Map是Key-Value映射关系,且Ke ...
- Java中的“==操作符”和equals方法有什么区别
Java中的"=="和equals方法究竟有什么区别? 1.==操作符 "=="操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的 ...
- 列举两种不同类型的Java标识注释,并解释它们之间的区别。
列举两种不同类型的Java标识注释,并解释它们之间的区别.
- java多线程之yield,join,wait,sleep的区别
Java多线程之yield,join,wait,sleep的区别 Java多线程中,经常会遇到yield,join,wait和sleep方法.容易混淆他们的功能及作用.自己仔细研究了下,他们主要的区别 ...
- JAVA基础2---深度解析A++和++A的区别
我们都知道JAVA中A++和++A在用法上的区别,都是自增,A++是先取值再自增,++A是先自增再取值,那么为什么会是这样的呢? 1.关于A++和++A的区别,下面的来看个例子: public cla ...
- Java Web开发和Python Web开发之间的区别
今天的文章讨论了Java Web开发和Python Web开发之间的区别.我不鼓励我们在这里从Java Web迁移到Python Web开发.我只是想谈谈我的感受.它不一定适合所有情况,仅供我们参考. ...
- 杂项-Java:jar 包与 war 包介绍与区别
ylbtech-杂项-Java:jar 包与 war 包介绍与区别 1.返回顶部 1. 做Java开发,jar包和war包接触的挺多的,有必要对它们做一个深入的了解,特总结整理如下: 1.jar包的介 ...
- “全栈2019”Java第一百一十章:局部内部类与匿名内部类区别详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- [转]Java五个最常用的集合类之间的区别和联系
Map<String, ?>只能是只读模式,不能增加,因为增加的时候不知道该写入什么类型的值:Map<String, Object>可以读和写,只要是所有Object类的子类都 ...
- java中,return和return null有什么区别吗?
java中,return和return null有什么区别吗? 最大的区别:return;方法的返回值必须是void!return null;方法的返回值必须不是 原始数据类型(封装类除过)和void ...
随机推荐
- JAVA object
1.toString 把对象变成字符串 对于一个引用型变量toString写不写都是一样的 2.equals() 比较两个对象的引用是否一样. 3. public class EqualsTest ...
- jquery 里面对数组去重操作-unique
js: var yearArray = new Array(2009, 2009, 2010, 2010, 2009, 2010); $.unique(yearArray); alert(yearAr ...
- CSS选定第k个元素
<!DOCTYPE html> <html> <head> <title></title> <style type="tex ...
- C语言与内存模型初探
#include<stdio.h> #include<string.h> int main(){ long long int a = 2<<30; char str ...
- [转]Hibernate延迟加载与opensessioninviewFilter
原文地址:http://blog.csdn.net/a19881029/article/details/7916702 hibernate延迟加载: 一个person对应多个school,使用hibe ...
- 【Ural】1519. Formula 1
http://acm.timus.ru/problem.aspx?space=1&num=1519 题意:给一个n×m的棋盘,其中'.'是空白,'*'是障碍,求经过所有点的哈密顿回路的数目.( ...
- Python3 函数
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可以自己创建函数,这 ...
- c# 集合
集合适用于元素个数是动态的情况. 当使用默认的构造函数创建一个空列表后(未指定容量),集合的容量为0:当往集合内添加元素,容量将变为4*2^n(n为0或正整数).当指定集合的大小为size后,容量将变 ...
- ionic+angularjs开发hybrid App(环境配置+创建测试项目)
本文使用的系统是win10 因为后期需要使用nodejs 所以先把node装好 https://nodejs.org/download/ 下载JDK并配置Java运行环境 http://www.ora ...
- 神经网络和Deep Learning
参考资料: 在线免费书籍 http://neuralnetworksanddeeplearning.com/chap1.html Chapter 1 1. perceptron 感知机 it's a ...