论坛首页 Java企业应用论坛

一道JAVA题

浏览 22655 次
锁定老帖子 主题:一道JAVA题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (4) :: 隐藏帖 (2)
作者 正文
   发表时间:2012-02-15  
最近同事出了个题给我做:

int j = 0;
for(int i=0; i<100; i++) {
  j = j++;
}

System.out.println(j);


我心里默算了一下,得出的结果是99,谁知运行下一看吓一跳。
   发表时间:2012-02-15  
看了下编译后的class文件,j = j++;  对应的虚拟机指令为:
   7: iload_1      //将j变量对应的值加载到栈顶
   8: iinc 1, 1      //变量j执行+1操作
   11: istore_1      //将栈顶的值保存到变量j中

第一次执行时,j=0,将j加载到栈顶,栈顶的值为0(7: iload_1),对变量j执行+1操作,j的值变成1(8: iinc 1, 1),将栈顶的值0写到变量j中,此时变量j的值变成0( 11: istore_1)。
0 请登录后投票
   发表时间:2012-02-15  
比较具有迷惑性
0 请登录后投票
   发表时间:2012-02-15  
public class Test {

    public static void main(String... args) {

         int i = 0;

         i = i++;

        System.out.println(i);

    }

}



使用javac编译后再使用javap -c Test反编译这个类查看它的字节码,如下(只摘取main方法):



public static void main(java.lang.String[]);

  Code:

   0:   iconst_0

   1:   istore_1

   2:   iload_1

   3:   iinc    1, 1

   6:   istore_1

   7:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;

   10:  iload_1

   11:  invokevirtual   #3; //Method java/io/PrintStream.println:(I)V

   14:  return

  

这里,我从第0行开始分析(分析中【】表示栈,栈的底端在左边,顶端在右边):

0:将常数0压入栈,栈内容:【0】

1:将栈顶的元素弹出,也就是0,保存到局部变量区索引为为1(也就是变量i)的地方。栈内容:【】

2:将局部变量区索引为1(也就是变量i)的值压入栈,栈内容:【0】

3:将局部变量区索引为1(也就是常量i)的值加一,此时局部变量区索引为1的值(也就是i的值)是1。栈内容:【0】

6:将栈顶元素弹出,保存到局部变量区索引为1(也就是i)的地方,此时i又变成了0。栈内容:【】

7:获取常量池中索引为2所表示的类变量,也就是System.out。栈元素:【】

10:将局部变量区索引为1的值(也就是i)压入栈。栈元素:【0】

11:调用常量池索引为3的方法,也就是System.out.println

14:返回main方法
1 请登录后投票
   发表时间:2012-02-15  
把代码做下面的变形和解释,相信你会理解的。
int j = 0; 
for(int i=0; i<100; i++) {
  int k = j; //保存++前的初始值
  j++; //执行++操作,这时j已经变成1了
  j = k; //把j执行++前的值赋给j,这时j由1又变成0了

 
System.out.println(j);//0

这里的用到了JAVA的基础知识右++的操作, 赋加之前的值

这样的知识点很小,仔细想想就会明白
0 请登录后投票
   发表时间:2012-02-16   最后修改:2012-02-16
这道题怎么也不能是99吧,即使j++也是100,当然j=j++结果就是0了。j++是先取值后做加法,每次取j都等于0
0 请登录后投票
   发表时间:2012-02-16   最后修改:2012-02-16
fuliang 写道
这道题怎么也不能是99吧,即使j++也是100,当然j=j++结果就是0了。j++是先取值后做加法,每次取j都等于0

+1


j=j++
换成
j++
楼主忽略了最重要的一步,最后退出循环时i的值应该是100,所以j应该是100

另外++符号与赋值同用的问题,javascript里也有同样的情况
var i=3;
i=i++;
alert(i); //3

这里的情况是:
先计算赋值右边表达式的结果,是3
将i自增1(后自增在返回结果后才运算)
将表达式结果赋与左边变量i
所以,i还是3
0 请登录后投票
   发表时间:2012-02-16  
很想知道LZ几年了?
0 请登录后投票
   发表时间:2012-02-16  
刚毕业不久
0 请登录后投票
   发表时间:2012-02-16  
看了以后也认为是99,不过仔细想想,还是0,j++先赋值后加1的
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics