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.