您的位置:首页 > 其它

一个表达式中对同一个变量多次赋值(i = i++)

2014-05-22 13:19 183 查看

问:

int i = 0;
i = ++i;
i的值是多少?毫无疑问,i = 1;但是,i = ++i;这条语句对i进行了两次赋值:第一次,i自增,此时i=1;第二次,将++i的表达式的值(也就是1)赋给i。我们通过字节码来分析一下这段代码的执行过程:

//int i = 0;的字节码
0:iconst_0 //将int型0推送至栈顶
1:istore_1 //将栈顶值(0)存入局部变量表中索引为1的地方(也就是i)

// i = ++i;的字节码
2:innc 1,1  //在局部变量表中索引为1的变量加1,此时i=1;
3:iload_1   //索引为1的变量值存入栈顶
4:istore_1  //将栈顶值存入索引为1的变量中


理解了上面的代码后,再考虑这样两行代码:

int i = 0;
i = i++;
这两条代码执行完成后,i的值是多少?答案是0。稍加思考,就会觉得这个结果并不是太意外,这两句代码的执行过程是这样的:

1))定义整型局部变量i,初始值为0;

2)JVM执行i++计算,该表达式的值为0;

3) i自增,i此时为1;

4)将i++表达式的值赋给i,i++表达式的值是0,所以赋值后,i = 0;

5)计算完毕,i = 0。

上面的每一步都不会让我们感到意外,为了更加清晰的说明问题,上面两行代码的等价代码如下:

int i = 0;

int tmp = 0;  //对应分析中的第(2)步,也就是i++表达式的值
i++;         //分析中的第(3)步
i = tmp;    //分析中的第(4)步


我们也从字节码看看这两条语句的执行过程:

//int i = 0;的字节码

0:iconst_0 //将int型0推送至栈顶,此时栈中的内容:[0]

1:istore_1 //将栈顶值(0)存入局部变量表中索引为1的地方(也就是i),i = 0;栈中的内容:[ ]

// i = i++;的字节码

2:iload_1 //索引为1的变量值存入栈顶,也就是i++表达式的值(0)存入栈顶,此时栈中的内容:[0]

3:innc 1,1 //在局部变量表中索引为1的变量加1,此时i=1;栈中的内容:[0]

4:istore_1 //将栈顶值(0)存入索引为1的变量中,i=0;栈中的内容:[ ]

从字节码中,我们可以看到:JVM首先把i++表达式的值存入到操作数栈中,也就是栈中保存着i = i++右半部的值(表达式i++,也就是0);然后把=右边的表达式计算完毕;最后将表达式i++的值赋给i(栈顶元素出栈,赋给i)。注意,i++是一个表达式,这个表达式的值是0。

这样的讨论其实是没有意义的,不要在一个表达式中,对同一个变量多次赋值!

参考资料:http://www.ticmy.com/?p=43(写这篇博客主要是为了加深自己的理解)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐