Я не уверен, есть ли в спецификации языка Java элемент, который диктует загрузку предыдущего значения переменной ...
Есть.В следующий раз, когда вам непонятно, что говорится в спецификации, прочитайте спецификацию и , затем задайте вопрос, если она неясна.
... правая сторона (x = y)
, которая,в порядке, подразумеваемом скобками, должен быть вычислен первым.
Это утверждение неверно. Скобки не подразумевают порядок оценки .В Java порядок вычисления слева направо, независимо от круглых скобок.Скобки определяют, где находятся границы подвыражения, а не порядок вычисления.
Почему первое выражение оценивается как ложное, а второе - как истинное?
Правилодля оператора ==
: вычисление левой стороны для получения значения, вычисление правой стороны для получения значения, сравнение значений, сравнение - это значение выражения.
Другими словами,значение expr1 == expr2
всегда такое же, как если бы вы написали temp1 = expr1; temp2 = expr2;
, а затем вычислили temp1 == temp2
.
Правило для оператора =
с локальной переменной слева: вычислитьлевая сторона для создания переменной, оценка правой стороны для получения значения, выполнение присваивания, результатом является значение, которое было присвоено.
Итак, сложите это вместе:
x == (x = y)
Мыесть оператор сравнения.Оцените левую сторону, чтобы получить значение - мы получаем текущее значение x
.Оцените правую сторону: это назначение, поэтому мы оцениваем левую сторону для получения переменной - переменной x
- мы оцениваем правую сторону - текущее значение y
- присваиваем ей x
,и результатом является присвоенное значение.Затем мы сравниваем исходное значение x
со значением, которое было присвоено.
Вы можете выполнить (x = y) == x
в качестве упражнения.Опять же, помните, все правила оценки левой стороны выполняются до того, как все правила оценки правой стороны .
Я ожидал (x = y), что будет оцениватьсясначала, а затем он сравнил бы x с самим собой (3) и вернул бы true.
Ваше ожидание основано на ряде неверных представлений о правилах Java.Надеюсь, теперь у вас есть правильные убеждения, и в будущем вы ожидаете истинных вещей.
Этот вопрос отличается от «порядка вычисления подвыражений в выражении Java»
Этоутверждение неверноЭтот вопрос совершенно уместен.
x здесь определенно не является «подвыражением».
Это утверждение также неверно.Это подвыражение дважды в каждом примере.
Его нужно загружать для сравнения, а не «оценивать».
Понятия не имею, что это значит.
Очевидно, у вас все еще много ложных убеждений.Мой совет, чтобы вы читали спецификацию, пока ваши ложные убеждения не будут заменены истинными убеждениями.
Вопрос специфичен для Java, а выражение x == (x = y), в отличие от надуманного, непрактичногоконструкции, обычно создаваемые для сложных вопросов интервью, взятые из реального проекта.
Происхождение выражения не имеет отношения к вопросу.Правила для таких выражений четко описаны в спецификации;прочитайте это!
Предполагалось, что это будет замена одной строки для идиомы сравнения и замены
Поскольку эта замена одной строки вызвала многоПутаница в вас, читатель кода, я бы предположил, что это был неудачный выбор.Делать код более кратким, но более сложным для понимания - не победа.Вряд ли код станет быстрее.
Кстати, в C # сравнивается и заменяется как библиотечный метод, который может быть привязан к машинной инструкции.Я считаю, что в Java такого метода нет, так как он не может быть представлен в системе типов Java.