概念
如++i
和i++
如果用于自增这两个是没有区别的,都相当于i=i+1
,但如果是通过这个来赋值如int a = i++;int b = ++j;
那么a保存i原有值,b= j+1
。
示例
1 | int i = 1; |
使用javap -c解开class后1
2
3
4
5
6
7
8
9
10
110: iconst_1 //从常量池取出1放入操作栈顶
1: istore_1 //把操作栈顶元素保存到本地变量i中 i=1
2: iconst_2 //从常量池取出2放入操作栈顶
3: istore_2 //把操作栈顶元素保存到本地变量j中 j=2
4: iload_1 //把本地变量i放入操作栈顶i=1
5: iinc 1, 1 //执行把本地变量i+1 ,操作栈顶不变
8: istore_3 //把操作栈顶元素保存到本地变量a中
9: iinc 2, 1 //执行把本地变量j+1 ,操作栈顶不变
12: iload_2 //把本来变量j放入栈顶 j=3
13: istore 4 //把栈顶j保存到本地变量,即b=3
15: return
- iconst:把
int
型数据放到操作栈顶。 - istore:把栈顶
int
元素保存到本地变量,移除栈顶元素。 - iload int:本地变量放入栈顶。
- iinc:把
int
元素自动+1,如iinc 1,1第一位是本地变量index
,第二位是+的数值。 - iinc:不会改变栈顶元素的值,它只会改变本地变量的值。
后++
的顺序是load ----iinc---store
先++
的顺序是iinc ----load---store
先前说过iinc
不会改变栈顶,会直接修改本地变量的值,所有后++
会把先前load
的值原封不动的保存进去,而先++
会先改变本地变量值,然后把本地变量捞取出来,再保存。
概念
例1
x=x+1,x+=1
及x++
的效率:x=x+1
最低,因为它的执行如下:
- 读取右x的地址;
x+1
;- 读取左x的地址;
- 将右值传给左边的x(编译器并不认为左右x的地址相同)。
x+=1
其次,它的执行如下:
- 读取x的地址;
- x+1;
- 将得到的值传给x(因为x的地址已经读出)。
x++
最高,它的执行如下:
- 读取右x的地址;
- x自增1。
例2
x=x+1
和x+=1
在什么情况下不成立而且x=x+1
是错误的(类型隐式转换)1
2
3short x=1;
x+=1;
x=x+1;
因为x是short类型,当它+1会自动转变成int(低字节向高字节进行转换,强制类型转换),当是等于又是short类型,所以会报错。
错误原因:x+=1
,int和short转换,转换成int,执行到x=x+1
时,x+1是int,高位不能转换成低位。