- package bishi;
- public class PlusPlusTest {
- public static void main(String[] args) {
- int i = 1;
- i = i++ + i++ + i++;
- System.out.println(i);
- int j = 1;
- j = ++j + ++j + ++j;
- System.out.println(j);
- }
- }
打印的i和j分别是多少呢?
先分析i++:
- int i = 1;
- i = i++ + i++ + i++;
- System.out.println(i);
- 0 iconst_1 //将int类型的数字1push到栈顶
- 1 istore_1 [i] //将栈顶的1存到变量i中, 这就是int i=1;
- 2 iload_1 [i] //把i的值再压栈,即栈顶存入1
- 3 iinc 1 1 [i] //把i变量中的值加1,此时i中存的是2,但是栈顶的值是1
- 6 iload_1 [i] //把i的值压栈,此时栈顶和栈顶第二个分别是2,1
- 7 iinc 1 1 [i] //把i变量中的值加1,此时i中存的是3,
- 10 iadd //把栈顶两个int类型的值相加,并把结果存入栈顶,即现在的栈,从栈顶往下依次存了3,2,1
- 11 iload_1 [i] //把i压栈,栈中自顶向下依次是3,3,2,1
- 12 iinc 1 1 [i] //把i变量中的值再加1,i中存的是4了
- 15 iadd //同10,执行完之后,栈顶为6
- 16 istore_1 [i] //将栈顶int型值存入i中,即执行完此步,i=6,到这一步就是整个 i = i++ + i++ + i++;
- 17 getstatic java.lang.System.out : java.io.PrintStream [16]
- 20 iload_1 [i] //这一步把i中的6再次push到栈顶
- 21 invokevirtual java.io.PrintStream.println(int) : void [22] //输出栈顶的6
java虚拟机内存空间中存在一个叫java方法栈的区域,在这里为每个方法提供一个栈帧,在栈帧中存放了该方法的局部变量表,操作栈,动态链接,方法出口等信息。上面字节码中指令所指的栈应该就是这个操作栈吧(个人理解,不保证正确~)。
分析完i++,下面来看看++j的原理
- int j = 1;
- j = ++j + ++j + ++j;
- System.out.println(j);
对应的字节码为:
- 24 iconst_1
- 25 istore_2 [j] //int j=1;
- 26 iinc 2 1 [j] //把j加1,j=2
- 29 iload_2 [j] //把j的值压栈,此时栈顶为2
- 30 iinc 2 1 [j] //把j加1,j=3
- 33 iload_2 [j] //把j的值压栈,栈顶往下依次为3,2
- 34 iadd //把栈顶两int类型数相加,结果压栈,栈顶往下:5,3,2
- 35 iinc 2 1 [j] //把j加1,j=4
- 38 iload_2 [j] //把j压栈,栈顶向下:4,5,3,2
- 39 iadd //把栈顶两int相加,结果压栈,栈顶往下:9,4,5,3,2
- 40 istore_2 [j] //把栈顶存入j,j=9,至此,j = ++j + ++j + ++j;执行完毕
- 41 getstatic java.lang.System.out : java.io.PrintStream [16]
- 44 iload_2 [j]
- 45 invokevirtual java.io.PrintStream.println(int) : void [22]
总结
i++和++i的区别就是在进入操作栈和自加的顺序,呃,说完怎么跟没说一样……