java中i=i++ 值无变化原因详解


  
  
  1. int i= 0;
  2. i=i++;
      结果i是多少?
      
      代码1:

  1. public   class  Test{
  2.      public   static   void  main(String[] args){
  3.           int  i= 0 ;
  4.          i=i++;
  5.          System.out.println(i);
  6.     }
  7. }

     结果i依然是0.

实际上


  
  
  1. int i= 0;
  2. i=i++;
等效于:


  
  
  1. int temp = i; //这个temp就是i++这个表达式的值
  2. i++; //i自增
  3. i = temp; //最终,将表达式的值赋值给i

分析其反编译后的代码:   

  1. public   static   void  main(java.lang.String[]);
  2.   Code:
  3.     0 :   iconst_0    
  4. //0放到栈顶
  5.     1 :   istore_1   
  6. //把栈顶的值保存到局部变量1,也就是i中
  7.     2 :   iload_1    
  8. //把i的值放到栈顶,也就是说此时栈顶的值是0
  9.     3 :   iinc     1 1 
  10. //注意这个指令,把局部变量1,也就是i,增加1,这个指令不会导致栈的变化,也就是说局部变量1,即i此时为1了。
  11.     6 :   istore_1    
  12. //把栈顶的值(0)保存到局部变量1,也就是让i为0了,所以最后i为0
  13.     7 :   getstatic   # 2 //Field java/lang/System.out:Ljava/io/PrintStream;
  14.     10 :  iload_1
  15.     11 :  invokevirtual   # 3 //Method java/io/PrintStream.println:(I)V
  16.     14 :   return

值得注意到是i被修改了两次,第一次是i++;i变为1,最后一次是i=0;所以结果i是0


代码2:

  1. public   class  Test2{
  2.      public   static   void  main(String[] args){
  3.           int  i= 0 ;
  4.           int  j= 0 ;
  5.          j=i++;
  6.          System.out.println(i);
  7.          System.out.println(j);
  8.     }
  9. }

这个结果肯定都知道,i是1,j是0.同样看反编译之后的代码: 

  1. public   static   void  main(java.lang.String[]);
  2.   Code:
  3.     0 :   iconst_0
  4.     1 :   istore_1    
  5. //i=0
  6.     2 :   iconst_0
  7.     3 :   istore_2    
  8. //j=0
  9.     4 :   iload_1     
  10. //把i的值放到栈顶,也就是说此时栈顶的值是0
  11.     5 :   iinc     1 1 
  12. //局部变量1加1,也就是让i++了,此时i已经是1了,上面说过,此指令不会导致栈变化
  13.     8 :   istore_2    
  14. //把栈顶的值(注意是0)存入局部变量2,也就是j中,所以j=0
  15.     9 :   getstatic   # 2 //Field java/lang/System.out:Ljava/io/PrintStream;
  16.     12 :  iload_1
  17.     13 :  invokevirtual   # 3 //Method java/io/PrintStream.println:(I)V
  18.     16 :  getstatic   # 2 //Field java/lang/System.out:Ljava/io/PrintStream;
  19.     19 :  iload_2
  20.     20 :  invokevirtual   # 3 //Method java/io/PrintStream.println:(I)V
  21.     23 :   return

很明显可以看出,java是先把i的值取出来放到栈顶,我们可以认为是引入了第三个变量int k=i;然后i++,这时候i为1了,然后让j=k;也就是0.结论,i的++运算是在对j这个变量的赋值之前完成的。

代码3:

  1. public   class  Test3{
  2.      public   static   void  main(String[] args){
  3.           int  i= 0 ;
  4.           int  j= 0 ;
  5.          j=++i;
  6.          System.out.println(i);
  7.          System.out.println(j);
  8.     }
  9. }

结果大家也都知道,i=1,j=1
看操作过程: 

  1. public   static   void  main(java.lang.String[]);
  2.   Code:
  3.     0 :   iconst_0    
  4.     1 :   istore_1   
  5. //i=0
  6.     2 :   iconst_0
  7.     3 :   istore_2    
  8. //j=0
  9.     4 :   iinc     1 1  
  10. //局部变量i加1,这时候i变成1了 。
  11.     7 :   iload_1    
  12. //把i的值放到栈顶,栈顶的值是1
  13.     8 :   istore_2   
  14. //j=1
  15.     9 :   getstatic   # 2 //Field java/lang/System.out:Ljava/io/PrintStream;
  16.     12 :  iload_1
  17.     13 :  invokevirtual   # 3 //Method java/io/PrintStream.println:(I)V
  18.     16 :  getstatic   # 2 //Field java/lang/System.out:Ljava/io/PrintStream;
  19.     19 :  iload_2
  20.     20 :  invokevirtual   # 3 //Method java/io/PrintStream.println:(I)V
  21.     23 :   return

对比代码2和代码3,关键的差别就是iload_1   个iinc这两条指令的位置变了。

 

 

当然:如果在C++中:上边的代码 运行结果必定是a=10.





				<script>
					(function(){
						function setArticleH(btnReadmore,posi){
							var winH = $(window).height();
							var articleBox = $("div.article_content");
							var artH = articleBox.height();
							if(artH > winH*posi){
								articleBox.css({
									'height':winH*posi+'px',
									'overflow':'hidden'
								})
								btnReadmore.click(function(){
									if(typeof window.localStorage === "object" && typeof window.csdn.anonymousUserLimit === "object"){
										if(!window.csdn.anonymousUserLimit.judgment()){
											window.csdn.anonymousUserLimit.Jumplogin();
											return false;
										}else if(!currentUserName){
											window.csdn.anonymousUserLimit.updata();
										}
									}
									
									articleBox.removeAttr("style");
									$(this).parent().remove();
								})
							}else{
								btnReadmore.parent().remove();
							}
						}
						var btnReadmore = $("#btn-readmore");
						if(btnReadmore.length>0){
							if(currentUserName){
								setArticleH(btnReadmore,3);
							}else{
								setArticleH(btnReadmore,1.2);
							}
						}
					})()
				</script>
				</article>

猜你喜欢

转载自blog.csdn.net/A_102/article/details/84842516