Если у меня есть следующий код:
array[index] = someValue;
сначала выполняется оценка someValue
или index
?
Если у меня есть следующий код:
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)