During the study of java expression calculation order I faced with one phenomenon I can't explain to myself clearly. There are two quiz questions. It is asked to define the console output.
Example 1
int[] a = {5, 5};
int b = 1;
a[b] = b = 0;
System.out.println(Arrays.toString(a));
Correct console output is: [5,0]
Example 2
public class MainClass {
static int f1(int i) {
System.out.print(i + ",");
return 0;
}
public static void main(String[] args) {
int i = 0;
i = i++ + f1(i);
System.out.print(i);
}
}
Correct console output is: 1,0
As I learned, there is operators groups (levels) with ordered precedence in java and expressions are evaluated according to operator precedence. Also there is associativity of each group and if operators have the same precedence, then they are evaluated in order specified by group associativity. The operators precedence table (from Cay S. Horstmann - Core Java V.1):
# operator associativity 1 [] . () method call left to right 2 ! ~ ++ -- + - (type) cast new right to left 3 * / % left to right 4 + - left to right ... 14 = += -= the rest are omitted right to left
With the table above it's become clear that in example 1 the operator with highest priority is array indexing a[b]
and then аssignment operators are evaluated from right to left: b=0
, then a[1]=0
. That is why a=[5,0]
.
But the example 2 confuses me. According to the precedence table, the operator with highest priority is f1(i)
method invocation (which should print 0
), then unary post-increment i++
(which uses current i=0
and increments it after), then addition operator 0+0
and аssignment operator finally i=0
. So, I supposed the correct output is 0,0
.
But in fact it is not. In fact the unary post-increment i++
is calculated first (increasing i
to 1
), then method invocation f1(i)
prints 1
and returns 0
and finally аssignment operator assigns i=0+0
, so the final i
value is 0
and correct answer is 1,0
.
I suppose this is so due to binary addition operator associativity "from left to right", but in this case why do addition is calculated first in example 2, but in example 1 the highest priority operator a[b]
is calculated first? I noticed that all operators in example 2 are in different groups, so we shouldn't take operator associativity into consideration at all, should we? Shouldn't we just order all operators from example 2 by precedence and evaluate it in resulting order?