24

为什么这个例子中的输出是1

public static void main(String[] args){
 int[] a = { 1, 2, 3, 4 };   
 int[] b = { 2, 3, 1, 0 };   
 System.out.println( a [ (a = b)[3] ] );   
}

我以为会是2。即,表达式被评估为:

a[(a=b)[3]]
a[b[3]]    //because a is now pointing to b
a[0]   

a[0] 不应该是2因为a指向b吗?

提前致谢。

4

4 回答 4

26

每个运算符的参数从左到右计算。即,在它的内容之前评估a前面[...]的,此时它仍然引用第一个数组。

于 2011-12-04T11:29:31.780 回答
16

这也让我很奇怪......但是,请在此处查看第 15.7.1 节

本质上,操作数是从左到右计算的。但也要注意这一点:

建议代码不要严重依赖本规范。当每个表达式最多包含一个副作用时,代码通常会更清晰,作为其最外层的操作,并且当代码不完全依赖于表达式的从左到右求值的结果出现的异常时。

于 2011-12-04T11:30:43.583 回答
7
a [ (a = b)[3] ] )

解释如下:

a = b => a = {2, 3, 1, 0};
( a = b )[3] => 0;

这是这里的技巧:a被评估为之前b分配给它的值。

a[(a = b)[3]) => a[0] = 1;

想想 Java 中的运算符优先级。它应该更明显一些。

于 2011-12-04T15:57:21.753 回答
2

正如 Marcelo Cantos 先生所指出的,每个运算符的参数都是从左到右评估的。因此,这就是我认为的执行方式

a[(a=b)[3]]

在这里,外部“a”将获取“1,2,3,4”,然后评估其参数 (a=b)[3]。因此现在 a=b 并返回 b 数组中索引 3 处的元素,该元素也由 a 指向。

因此,我们从参数评估中得到“0”。如前所述,外部 a 仍然引用旧内容因此在 1,2,3,4 数组中给出 a[0]。

因此我们得到一个'1'。

这是我的理解。请让我知道它是否错了。

谢谢,

于 2014-08-19T23:43:25.617 回答