2011-12-04 113 views
24

为什么在这个例子中的输出是?Java数组 - 为什么输出为'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] ]); 
} 

我认为这将是。即,表达被评价为:

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

如果不是[0]是因为一个指向b

在此先感谢。

+3

男人,C有这非常简单的“未定义的行为”的事情! – Kos

+2

奇怪的学习+1! –

+1

这些是一些Java测试或面试者想要问的问题,即使没有人理智也会写这样的代码。 – GreenieMeanie

回答

16

这weirded我出去,以及...但是,检查节15.7.1在here

从本质上讲,由左到右的操作数进行评估。但是请注意:

建议代码不要严格依赖于此规范。当每个表达式至多包含一个副作用时,代码通常会更清晰,作为其最外层操作,并且代码并不完全依赖于由表达式的从左到右的评估导致出现哪种异常。

+1

我一直认为括号首先被评估 - BODMAS – ziggy

26

每个运算符的参数从左到右进行评估。即,在[...]之前的a在其内容之前被评估,此时它仍然指向第一个数组。

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中的运算符优先级。它应该更明显一点。

+0

-1:OP询问了为什么,你只是表明当你重新排序指令时可能得到1 ... – Betlista

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数组中给出了一个[0]。

因此我们得到'1'。

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

谢谢,