24

Why is the output in this example 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] ] );   
}

I thought it would be 2. i.e., the expression is evaluated as:

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

Shouldn't a[0] be 2 because a is pointing to b?

Thanks in advance.

Kris
  • 312
  • 2
  • 13
ziggy
  • 15,677
  • 67
  • 194
  • 287
  • 3
    Man, C has this so much simpler with that "undefined behaviour" thing! – Kos Dec 04 '11 at 21:53
  • 1
    These are the kind of questions some Java tests or interviewers would love to ask, even though no one who is sane would ever write code like that. – GreenieMeanie Dec 08 '11 at 18:13
  • Yes i am studying for the SCJP certification and the question came up in one of the examples. – ziggy Dec 08 '11 at 19:21
  • Personally i dont think it is fair to ask this kind of question in an interview. – ziggy Dec 08 '11 at 19:21

4 Answers4

26

The arguments to each operator are evaluated left-to-right. I.e., the a in front of the [...] is evaluated before its contents, at which point it still refers to the first array.

Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
16

That weirded me out as well... however, check section 15.7.1 over here

Essentially, operands are evaluated from left to right. But also note this:

It is recommended that code not rely crucially on this specification. Code is usually clearer when each expression contains at most one side effect, as its outermost operation, and when code does not depend on exactly which exception arises as a consequence of the left-to-right evaluation of expressions.

Miquel
  • 15,405
  • 8
  • 54
  • 87
7
a [ (a = b)[3] ] )

is interpreted as follows:

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

Here is the trick here: a is evaluated as the value before b is assigned to it.

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

Think about the operator precedence in Java. It should be a bit more obvious.

Yi Jiang
  • 49,435
  • 16
  • 136
  • 136
Wangge
  • 462
  • 1
  • 4
  • 9
2

As Mr Marcelo Cantos Pointed out, Arguments to each operator are evaluated from left to right. Therefore here is what I think the execution is

a[(a=b)[3]]

Here the outer 'a' will fetch "1,2,3,4" and then its argument (a=b)[3] is evaluated. Thus now a=b and the element at index 3 in b array is returned which is also pointed by a.

Hence we get a '0' from the argument evaluation. As said previously, outer a still refers to old contents Thus gives a[0] in 1,2,3,4 array.

Therefore we get a '1'.

This is my understanding. Please let me know if its wrong.

Thanks,