Подтвердить что ты не робот

Тернарный оператор, синтаксическая ошибка при использовании назначения

Следующие 3 строки кода ниже компилируются ОК. (Обратите внимание, что этот код является примером "искусственного кодирования Java" и, следовательно, не будет рассматриваться в профессионально написанном коде.)

int x, y;
boolean b=true;

x = b ? y=1 : 2;  // Compiles OK.

Если теперь изменить код в строке № 3 выше, так что он выглядит как следующая строка кода ниже, компилятор генерирует ошибку.

// Change the position of the "y assignment", and now the code doesn't compile.
x = b ? 1 : y=2;  

Вот сообщение об ошибке синтаксиса:

Ternary operator syntax error

Может кто-нибудь объяснить это поведение (для новичков Java-обучения)? Спасибо.

4b9b3361

Ответ 1

Короткие

Это связано с приоритетом оператора. Первый случай равен этому:

x = (b ? (y=1) : 2);  // Compiles OK.

Пока второе:

x = (b ? 1 : y) = 2;  

Первый компилируется действительно отлично, потому что присваивание получает новое значение. Таким образом, если b истинно, это приведет к тому, что оба значения x и y равны 1. Второе похоже на высказывание: x = 1 = 2. Итак, да, чтобы исправить эту ошибку компилятора, добавьте paratheses в ваш оператор:

x = (b ? 1 : (y = 2));  // Outer () are not needed, but is clearer, IMHO.

Более длинные:

Прежде всего, приоритет оператора в Java говорит, что операторы присваивания имеют более низкий приоритет, чем условный тернарный оператор. Это означает, что ваше второе выражение эквивалентно:

x = (b ? 1 : y) = 2;

Как вы можете видеть, это выглядит неправильно. Действительно, JLS §15.26 говорит следующее:

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

Результатом первого операнда оператора присваивания должна быть переменная, или возникает ошибка времени компиляции. (Это объясняет ошибку времени компиляции)

Во время выполнения результатом выражения присваивания является значение переменной после того, как произошло присвоение. Результат выражения присваивания сам по себе не является переменной.

Применение правой ассоциативности:

x = ((b ? 1 : y) = 2);

Наконец, мы можем понять, почему это порождает ошибку компилятора: результат тернарного условного оператора не является переменной (которая на самом деле не находится в JLS, насколько я могу найти, однако компилятор говорит вам в простом примере теста как этот: https://ideone.com/kMr7Xv).

Ответ 2

См. "Приоритет Java-операторов". Между тем, используйте:

x = (b ? 1 : (y=2)); 

Ответ 3

Приоритет Java-операторов выглядит следующим образом

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

здесь ternary предшествует операции assignment. поэтому ваше утверждение будет таким:

x = (тройная оценка) = значение присваивания

если вы все еще хотите установить значение для y, когда b является ложным, вы можете использовать () для 'y = 2', чтобы ввести тройную оценку.

x = b ? 1 : (y=2);

Ответ 4

Брат, попробуйте положить выражения в скобки.

X = (b≤1: (y = 2));

это будет работать нормально.