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

следующие 3 строки кода ниже компилируют OK. (Обратите внимание, что этот код является примером "искусственного кодирования 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 learner)? Спасибо.

4 ответов


Short:

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

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 to b и затем присваивает значение b to a.

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

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

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

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

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


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

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

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

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

здесь ternary перед assignment операции. таким образом, ваше заявление будет таким

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

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

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

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

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

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