是否首先评估数组索引或指定值?
如果我有以下代码:
array[index] = someValue;
someValue
或index
是否先被评估?
首先评估索引。 见JLS第15.26.1节 ,特别是:
15.26.1。 简单的分配操作符=
…
如果左侧操作数是数组访问表达式(第15.13节),可能包含在一对或多对括号中,则:
首先,评估左侧操作数数组访问表达式的数组引用子表达式。 如果此评估突然完成,则赋值表达式出于同样的原因突然完成; 不评估索引子表达式(左侧操作数数组访问表达式)和右侧操作数,并且不进行赋值。
否则,将评估左侧操作数数组访问表达式的索引子表达式。 如果此评估突然完成,则赋值表达式会出于同样的原因突然完成,并且不会评估右侧操作数,也不会发生赋值。
否则,将评估右侧操作数。 如果此评估突然完成,则赋值表达式会出于同样的原因突然完成,并且不会发生任何分配。
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)