为何i += i + a[i++] + a[i++] + a[i++]结果为8?Java表达式求值疑问
拆解Java中i += 表达式里的自增迷惑行为
嘿,这个问题其实戳中了Java表达式求值里特别容易踩坑的点——操作数的严格左到右求值顺序和i++的即时副作用结合在一起的情况,我给你一步步拆解清楚:
首先先明确Java的核心规则:
- Java对表达式的操作数是严格从左到右求值的;
- 每一个操作数求值完成后,它的副作用(比如
i++修改i的值)会立刻生效,不会等到整个表达式结束才更新。
第一个例子拆解
先看你第一段代码:
int i = 1; int[] a = new int[6]; a[0] = 0; a[1] = 1; a[2] = 2; a[3] = 3; a[4] = 4; a[5] = 5; i += i + a[i++] + a[i++]; // 执行后i的值为5
首先i += x等价于i = (原来的i值) + x,但要注意:这里的“原来的i值”是计算整个右表达式之前的i值,但右表达式内部的每个操作数会从左到右依次求值,且i++会实时改变i:
- 先确定左操作数
i的初始值:1; - 计算右表达式
i + a[i++] + a[i++],从左到右一步步来:- 第一个操作数
i:当前i=1,取到值1; - 第二个操作数
a[i++]:i++是后置自增,先返回当前i的值(1),然后立刻把i改成2,所以取到a[1]=1; - 第三个操作数
a[i++]:此时i已经是2了,i++返回2,i立刻改成3,取到a[2]=2;
- 第一个操作数
- 右表达式的总和是
1+1+2=4; - 最后计算
i = 初始值1 + 4 = 5,所以最终i=5。
第二个例子拆解
再看第二段代码:
i = 1; i += i + a[i++] + a[i++] + a[i++]; // 执行后i的值为8
逻辑和第一个完全一致,只是多了一个a[i++]:
- 左操作数
i的初始值还是1; - 计算右表达式
i + a[i++] + a[i++] + a[i++]:- 第一个
i:取到值1; a[i++]:i=1→返回1,i变成2,取a[1]=1;a[i++]:i=2→返回2,i变成3,取a[2]=2;a[i++]:i=3→返回3,i变成4,取a[3]=3;
- 第一个
- 右表达式总和是
1+1+2+3=7; - 最后
i=1+7=8,和你的结果完全匹配。
纠正你的错误认知
你之前以为“i=1会被缓存且不会改变”是不对的——Java不会缓存初始i值,在右表达式求值过程中,i++的副作用会实时修改i,后面的操作数求值时会直接用更新后的i值。而你说的“表达式严格按从左到右顺序求值”是对的,但忽略了i++的即时副作用,这才是迷惑你的关键。
最后提一句:这种写法在实际开发中一定要避免!可读性极差,很容易出错,而且换成C/C++这种语言,这种表达式属于未定义行为(不同编译器可能给出不同结果),只有Java是明确定义了求值顺序的。
内容的提问来源于stack exchange,提问作者Code Complete
相关产品推荐
相关产品推荐

