java中i++和++i

转:http://blog.csdn.net/damoyan/article/details/7384602


这几天抽着一些时间,把Java的class文件结构研究了一下,再后来就想起了这个令人厌烦的问题,想从字节码指令的角度看看,java到底是怎么处理这个的

先看一段java代码

  1. package bishi;  
  2.   
  3. public class PlusPlusTest {  
  4.       
  5.     public static void main(String[] args) {  
  6.   
  7.         int i = 1;  
  8.         i = i++ + i++ + i++;  
  9.         System.out.println(i);  
  10.         int j = 1;  
  11.         j = ++j + ++j + ++j;  
  12.         System.out.println(j);  
  13.     }  
  14.   
  15. }  
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++:

  1. int i = 1;  
  2. i = i++ + i++ + i++;  
  3. System.out.println(i);  
		int i = 1;
		i = i++ + i++ + i++;
		System.out.println(i);

这三句对应的字节码为:

  1. 0  iconst_1       //将int类型的数字1push到栈顶  
  2. 1  istore_1 [i]   //将栈顶的1存到变量i中, 这就是int i=1;  
     0  iconst_1       //将int类型的数字1push到栈顶
     1  istore_1 [i]   //将栈顶的1存到变量i中, 这就是int i=1;
  1.  2  iload_1 [i]    //把i的值再压栈,即栈顶存入1  
  2.  3  iinc 1 1 [i]   //把i变量中的值加1,此时i中存的是2,但是栈顶的值是1  
  3.  6  iload_1 [i]    //把i的值压栈,此时栈顶和栈顶第二个分别是2,1  
  4.  7  iinc 1 1 [i]   //把i变量中的值加1,此时i中存的是3,  
  5. 10  iadd           //把栈顶两个int类型的值相加,并把结果存入栈顶,即现在的栈,从栈顶往下依次存了3,2,1  
  6. 11  iload_1 [i]    //把i压栈,栈中自顶向下依次是3,3,2,1  
  7. 12  iinc 1 1 [i]   //把i变量中的值再加1,i中存的是4了  
  8. 15  iadd           //同10,执行完之后,栈顶为6  
  9. 16  istore_1 [i]   //将栈顶int型值存入i中,即执行完此步,i=6,到这一步就是整个 i = i++ + i++ + i++;  
  10. 17  getstatic java.lang.System.out : java.io.PrintStream [16]  
  11. 20  iload_1 [i]    //这一步把i中的6再次push到栈顶  
  12. 21  invokevirtual java.io.PrintStream.println(int) : void [22]   //输出栈顶的6  
     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的原理

  1. int j = 1;  
  2. j = ++j + ++j + ++j;  
  3. System.out.println(j);  
		int j = 1;
		j = ++j + ++j + ++j;
		System.out.println(j);

对应的字节码为:

  1. 24  iconst_1           
  2. 25  istore_2 [j]     //int j=1;  
  3. 26  iinc 2 1 [j]     //把j加1,j=2  
  4. 29  iload_2 [j]      //把j的值压栈,此时栈顶为2  
  5. 30  iinc 2 1 [j]     //把j加1,j=3  
  6. 33  iload_2 [j]      //把j的值压栈,栈顶往下依次为3,2  
  7. 34  iadd             //把栈顶两int类型数相加,结果压栈,栈顶往下:5,3,2  
  8. 35  iinc 2 1 [j]     //把j加1,j=4  
  9. 38  iload_2 [j]      //把j压栈,栈顶向下:4,5,3,2  
  10. 39  iadd             //把栈顶两int相加,结果压栈,栈顶往下:9,4,5,3,2  
  11. 40  istore_2 [j]     //把栈顶存入j,j=9,至此,j = ++j + ++j + ++j;执行完毕  
  12. 41  getstatic java.lang.System.out : java.io.PrintStream [16]  
  13. 44  iload_2 [j]  
  14. 45  invokevirtual java.io.PrintStream.println(int) : void [22]  
    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的区别就是在进入操作栈和自加的顺序,呃,说完怎么跟没说一样……


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值