Java 中的 i = i++ 问题
int i = 0;
i = i++;
System.out.println(i); // 0
问最后的输出结果是什么。我这两天才开始看 Java,第一眼就认为肯定是输出 1 ,但如果结果真的这么直观就不会出成笔试题了。实际运行一下,结果居然是输出 0。
如果把 i = i++
换成 i = ++i
或者干脆换成 i++
。输出结果就是 1 了。为了完整性,把替换后的代码也贴一下。
int i = 0;
i++;
System.out.println(i); // 1
int i = 0;
i = ++i;
System.out.println(i); // 1
解释
这个问题其实想明白了就很简单,只需要理解两个关键的地方:1. 表达式的返回值。 2. 临时变量。不信我们先来分析大家都知道的 i++
和 ++i
的区别。假设有下面一段 Java 代码:
// e.g.1
int i = 0;
int j = 0;
int a = ++i; // a=1, i=1
int b = j++; // b=0, j=1
问最后 i j a b 的值各是什么。相信很多人都能得到正确答案。所以我把答案直接注释在代码中了。很多人也能解释个所以然来。但我们还是来分析一下:
a 的结果是表达式 ++i
的值,而 b 的结果是表达式 j++
的值。大多数人都知道 ++i
返回的是 i 自增以后的值,而 j++
返回的是 j 自增以前的值。a b 值不一样,也就是表达式 ++i
和表达式 j++
的返回值不一样。
上面说这么啰嗦就是为了让大家注意到表达式的返回值的概念。表达式都是有返回值的,不然就不能放在赋值操作符右边了。而且无论多么复杂的表达式都是在表达式计算完后才返回一个值(注意是计算完后)。表达式 ++i
的返回值就是 i 自增后的值,而表达式 j++
的返回值是 j 自增前的值。
OK,我们终于引入了表达式的返回值这个概念。再思考一下, 表达式 ++i
直接在 i 自增完后返回 i 的值就行。那 j++
要返回 j 自增前的值,怎么做到?难道先返回 j 的值,然后再让 j 自增吗?不行,因为表达式计算结束后才能返回一个值。编译器普遍的做法是创建一个临时变量来保存 j 自增前的值,在 j 自增完后再返回这个临时变量的值。所以 b = j++
底层发生的步骤如下:
step1: temp = j; // 创建一个临时变量 temp 保存 j 的值,这个 temp 也是整个表达式的返回值
step2: 对 j 进行自增操作
step3: 将表达式的返回值 temp 赋值给 b
- 1
- 2
- 3
然后临时变量 temp
的使命就完成了。
注:可能有部分人误以为:表达式 j++ 是先返回 j 的值,然后再对 j 进行自增操作。这种理解是错误的。如果表达式都返回了,还计算个球。表达式只有在计算完后才会进行返回。无论多么复杂的表达式,返回值都在最后一步。
OK,到了这里,原始问题就很清晰了。
int i = 0;
i = i++;
System.out.println(i); // 0
- 1
- 2
- 3
中 i = i++
对应的步骤如下:
step1: 创建一个临时变量 temp 保存 i 的值 // temp=i=0,temp 也是整个表达式的返回值
step2: 对 i 进行自增操作 // i 的值变成了 1
step3: 返回表达式的值,也就是将 temp 赋值 给 i // i 的值变成了 temp 的值,所以 i 又变成了 0
--------------------- 作者:流沙的刺客 来源:CSDN 原文:https://blog.csdn.net/candcplusplus/article/details/54558333?utm_source=copy 版权声明:本文为博主原创文章,转载请附上博文链接!