Java - порядок операций - использование двух операторов присваивания в одной строке
Каков порядок операций при использовании двух операторов присваивания в одной строке?
public static void main(String[] args){
int i = 0;
int[] a = {3, 6};
a[i] = i = 9; // this line in particular
System.out.println(i + " " + a[0] + " " + a[1]);
}
Изменить: Спасибо за сообщения. Я получаю, что = принимает значения справа, но когда я скомпилирую это, я получаю:
9 9 6
Я думал, что это было бы и исключение ArrayOutOfBounds, но он назначает 'a [i]' перед тем, как он переместится через 9. Это просто делает это для массивов?
Ответы
Ответ 1
=
анализируется как право-ассоциативный, но порядок оценки слева направо.
Итак: оператор анализируется как a[i] = (i = 9)
. Однако выражение i
в a[i]
оценивается перед правой частью (i = 9
), когда i
все еще 0
.
Это эквивалент чего-то вроде:
int[] #0 = a;
int #1 = i;
int #2 = 9;
i = #2;
#0[#1] = #2;
Ответ 2
Согласно спецификациям:
15.26 Операторы присваивания Существует 12 операторов назначения; все они синтаксически правые ассоциативные (они группируются справа налево). Таким образом, a = b = c означает a = (b = c), который присваивает значение c в b и затем присваивает значение b a.
Итак, a[i] = i = 9;
совпадает с i = 9; a[i] = i;
Edit
Собственно, это не так. Пример тестового класса:
import java.util.Arrays;
public class Mkt {
public static void main(String[] args) {
int[] a = new int[10];
int i = 5;
a[i] = i = 9;
System.out.println(Arrays.toString(a));
}
}
Пример прогона:
$ javac Mkt.java && java Mkt
[0, 0, 0, 0, 0, 9, 0, 0, 0, 0]
Дополнительную информацию см. в другом ответе. В основном:
-
a[i] = i = 9
совпадает с a[i] = (i = 9)
, так как =
является право-ассоциативным
-
Однако, оценка операнда слева направо, согласно this:
15,7. Порядок оценки
Язык программирования Java гарантирует, что операнды операторов будут оцениваться в определенном порядке оценки, а именно слева направо.
Рекомендуется, чтобы код не опирался на эту спецификацию. Код обычно более ясен, когда каждое выражение содержит не более одного побочного эффекта, как его внешнюю операцию, и когда код не зависит от того, какое именно исключение возникает из-за оценки выражений слева направо.
Я скопировал второй абзац, который очень поучителен здесь - редко имеет смысл писать путающий код, подобный этому.
Я также считаю, что этот стоит проверить.
Ответ 3
Если я правильно помню, = оператор является право-ассоциативным; поэтому я буду назначен первым, затем [i].
Ответ 4
Оператор =
является право-ассоциативным (как уже говорили другие). Это легко проверить с помощью этого теста:
int i = 2;
int j = 3;
int x = i = j;
System.out.println(x); // This prints out 3.
Это работает со всеми типами, объектами и примитивами.
Я слышал, что это называется "двойное присвоение", поскольку, используя приведенный выше пример, вы присваиваете значение j
как i
, так и x
.