Java - порядок операций - использование двух операторов присваивания в одной строке - PullRequest
13 голосов
/ 25 февраля 2012

Каков порядок операций при использовании двух операторов присваивания в одной строке?

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, но он присваивает '[i]' до того, как переместится через 9. Это просто делает это для массивов?

Ответы [ 4 ]

12 голосов
/ 25 февраля 2012

= анализируется как ассоциативный справа, но порядок оценки слева направо.

Итак: оператор анализируется как 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;
6 голосов
/ 25 февраля 2012

Согласно спецификации:

15.26 Операторы присваивания Есть 12 операторов присваивания;все синтаксически справа ассоциативны (они группируются справа налево).Таким образом, a = b = c означает a = (b = c), который присваивает значение c b и затем присваивает значение b a.

Итак, a[i] = i = 9; являетсятак же, как i = 9; a[i] = i;

Редактировать

На самом деле это не так.Пример тестового класса:

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), так как = является ассоциативным справа
  • Однако, операнд оценка равнаслева направо, согласно это :

    15,7.Порядок оценки

    Язык программирования Java гарантирует, что операнды операторов, по-видимому, будут оцениваться в определенном порядке оценки, а именно слева направо.

    Рекомендуется, чтобы код не полагался критически наэта спецификация.Код обычно более понятен, если каждое выражение содержит не более одного побочного эффекта в качестве самой внешней операции, и когда код не зависит от того, какое именно исключение возникает в результате вычисления выражений слева направо.

Я скопировал второй абзац, который очень поучителен здесь - редко имеет смысл писать такой запутанный код.

Я также считаю этим достойным внимания.

2 голосов
/ 25 февраля 2012

Если я правильно помню, = оператор является правоассоциативным; поэтому сначала меня назначат, затем [i].

0 голосов
/ 25 февраля 2012

Оператор = является ассоциативным справа (как уже говорили другие).Это легко проверить с помощью этого теста:

int i = 2;
int j = 3;
int x = i = j;
System.out.println(x); // This prints out 3.

Это работает со всеми типами, объектами и примитивами.

Я слышал, что это называется «двойным назначением», посколькуиспользуя приведенный выше пример, вы присваиваете значение j для i и x.

...