是否首先评估数组索引或指定值?

如果我有以下代码:

array[index] = someValue; 

someValueindex是否先被评估?

首先评估索引。 见JLS第15.26.1节 ,特别是:

15.26.1。 简单的分配操作符=

如果左侧操作数是数组访问表达式(第15.13节),可能包含在一对或多对括号中,则:

  1. 首先,评估左侧操作数数组访问表达式的数组引用子表达式。 如果此评估突然完成,则赋值表达式出于同样的原因突然完成; 不评估索引子表达式(左侧操作数数组访问表达式)和右侧操作数,并且不进行赋值。

  2. 否则,将评估左侧操作数数组访问表达式的索引子表达式。 如果此评估突然完成,则赋值表达式会出于同样的原因突然完成,并且不会评估右侧操作数,也不会发生赋值。

  3. 否则,将评估右侧操作数。 如果此评估突然完成,则赋值表达式会出于同样的原因突然完成,并且不会发生任何分配。

TL; DR :顺序为1 [2] = 3

看起来首先评估index表达式。

该测试程序证实了这一点:

 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; } } 

输出:

 getIndex! getValue! 

即使抛出ArrayIndexOutOfBoundsException也会计算该值。 更改getIndex()

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

输出:

 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)