Não tenho certeza se existe um item na Especificação de Linguagem Java que determina o carregamento do valor anterior de uma variável ...
Há sim. Da próxima vez que você está claro o que a especificação diz, por favor leia a especificação e , em seguida, fazer a pergunta se não está claro.
... o lado direito (x = y)
que, pela ordem implícita entre parênteses, deve ser calculado primeiro.
Essa afirmação é falsa. Parênteses não implicam uma ordem de avaliação . Em Java, a ordem da avaliação é da esquerda para a direita, independentemente dos parênteses. Parênteses determinam onde estão os limites da subexpressão, e não a ordem da avaliação.
Por que a primeira expressão é avaliada como falsa, mas a segunda é avaliada como verdadeira?
A regra para o ==
operador é: avalie o lado esquerdo para produzir um valor, avalie o lado direito para produzir um valor, compare os valores, a comparação é o valor da expressão.
Em outras palavras, o significado de expr1 == expr2
é sempre o mesmo que se você tivesse escrito temp1 = expr1; temp2 = expr2;
e avaliado temp1 == temp2
.
A regra para o =
operador com uma variável local no lado esquerdo é: avalie o lado esquerdo para produzir uma variável, avalie o lado direito para produzir um valor, execute a atribuição, o resultado é o valor que foi atribuído.
Então junte-o:
x == (x = y)
Temos um operador de comparação. Avalie o lado esquerdo para produzir um valor - obtemos o valor atual de x
. Avalie o lado direito: é uma atribuição, portanto, avaliamos o lado esquerdo para produzir uma variável - a variável x
- avaliamos o lado direito - o valor atual de y
- atribua a ela x
e o resultado é o valor atribuído. Em seguida, comparamos o valor original x
com o valor atribuído.
Você pode fazer (x = y) == x
como um exercício. Novamente, lembre-se de que todas as regras para avaliar o lado esquerdo acontecem antes de todas as regras de avaliação do lado direito .
Eu esperaria que (x = y) fosse avaliado primeiro e, em seguida, ele compararia x consigo (3) e retornaria true.
Sua expectativa é baseada em um conjunto de crenças incorretas sobre as regras do Java. Espero que agora você tenha crenças corretas e, no futuro, espere coisas verdadeiras.
Esta pergunta é diferente de "ordem de avaliação de subexpressões em uma expressão Java"
Esta afirmação é falsa. Essa pergunta é totalmente pertinente.
x definitivamente não é uma 'subexpressão' aqui.
Esta afirmação também é falsa. É uma subexpressão duas vezes em cada exemplo.
Ele precisa ser carregado para a comparação, em vez de ser 'avaliado'.
Eu não tenho ideia do que isso significa.
Aparentemente, você ainda tem muitas crenças falsas. Meu conselho é que você leia a especificação até que suas falsas crenças sejam substituídas por verdadeiras.
A pergunta é específica de Java e a expressão x == (x = y), ao contrário de construções práticas pouco buscadas comumente criadas para perguntas difíceis de entrevistas, veio de um projeto real.
A proveniência da expressão não é relevante para a questão. As regras para tais expressões estão claramente descritas na especificação; Leia-o!
Era para ser uma substituição de uma linha para o idioma comparar e substituir
Como essa substituição de uma linha causou muita confusão em você, leitor do código, eu sugeriria que era uma má escolha. Tornar o código mais conciso, mas mais difícil de entender, não é uma vitória. É improvável que o código seja mais rápido.
Aliás, o C # compara e substitui como um método de biblioteca, que pode ser associado a uma instrução de máquina. Acredito que o Java não possui esse método, pois não pode ser representado no sistema do tipo Java.