11

If I have the following code:

array[index] = someValue;

does the someValue or the index get evaluated first?

tbodt
  • 16,609
  • 6
  • 58
  • 83

2 Answers2

19

The index is evaluated first. See JLS section 15.26.1, in particular:

15.26.1. Simple Assignment Operator =

...

If the left-hand operand is an array access expression (§15.13), possibly enclosed in one or more pairs of parentheses, then:

  1. First, the array reference subexpression of the left-hand operand array access expression is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the index subexpression (of the left-hand operand array access expression) and the right-hand operand are not evaluated and no assignment occurs.

  2. Otherwise, the index subexpression of the left-hand operand array access expression is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and the right-hand operand is not evaluated and no assignment occurs.

  3. Otherwise, the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.

TL;DR: The order is 1[2]=3

Jason C
  • 38,729
  • 14
  • 126
  • 182
6

It looks like the index expression is evaluated first.

This test program confirms it:

public class Main {
   public static void main(String[] args) {
      int[] array = new int[10];
      array[getIndex()] = getValue();
   }


   private static int getIndex() {
      System.out.println("getIndex!");
      return 0;
   }

   private static int getValue() {
      System.out.println("getValue!");
      return 1;
   }
}

Output:

getIndex!
getValue!

The value is evaluated even if an ArrayIndexOutOfBoundsException is thrown. Changing getIndex():

private static int getIndex() {
   System.out.println("getIndex!");
   return -1;  // Hey!
}

Output:

getIndex!
getValue!
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
    at Main.main(Main.java:11)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
rgettman
  • 176,041
  • 30
  • 275
  • 357
  • The question is, will it do this for every JVM? Is there a guarantee? – tbodt Dec 02 '13 at 22:38
  • @tbodt Yes every compiler will generate code that behaves this way; the evaluation order is specified in the JLS. – Jason C Dec 02 '13 at 22:41
  • 1
    it's a compiler issue not a JVM issue. from jls `The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.` – BevynQ Dec 02 '13 at 22:42
  • @Downvoter Please explain what is wrong/can be corrected. – rgettman Dec 02 '13 at 22:44