Java arrays - Why is the output '1' ?
Asked Answered
S

4

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.

Samellasameness answered 4/12, 2011 at 11:25 Comment(4)
Man, C has this so much simpler with that "undefined behaviour" thing!Breakage
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.Sholokhov
Yes i am studying for the SCJP certification and the question came up in one of the examples.Samellasameness
Personally i dont think it is fair to ask this kind of question in an interview.Samellasameness
P
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.

Periderm answered 4/12, 2011 at 11:30 Comment(1)
I always thought that brackets are evaluated first - BODMASSamellasameness
O
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.

Orthographize answered 4/12, 2011 at 11:29 Comment(0)
P
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.

Periderm answered 4/12, 2011 at 11:30 Comment(1)
I always thought that brackets are evaluated first - BODMASSamellasameness
W
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.

Warden answered 4/12, 2011 at 15:57 Comment(1)
-1: the OP asked why, you just showed that it's possible to get 1 when you reorder instructions...Mauritamauritania
L
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,

Lilt answered 19/8, 2014 at 23:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.