No estoy seguro de si hay un elemento en la Especificación del lenguaje Java que dicta cargar el valor anterior de una variable ...
Ahi esta. La próxima vez que no tenga claro qué dice la especificación, lea la especificación y luego haga la pregunta si no está clara.
... el lado derecho (x = y)
que, por el orden implicado entre paréntesis, debe calcularse primero.
Esa afirmación es falsa. Los paréntesis no implican un orden de evaluación . En Java, el orden de evaluación es de izquierda a derecha, independientemente de los paréntesis. Los paréntesis determinan dónde están los límites de subexpresión, no el orden de evaluación.
¿Por qué la primera expresión se evalúa como falsa, pero la segunda se evalúa como verdadera?
La regla para el ==
operador es: evaluar el lado izquierdo para producir un valor, evaluar el lado derecho para producir un valor, comparar los valores, la comparación es el valor de la expresión.
En otras palabras, el significado de expr1 == expr2
siempre es el mismo que si hubiera escrito temp1 = expr1; temp2 = expr2;
y luego evaluado temp1 == temp2
.
La regla para el =
operador con una variable local en el lado izquierdo es: evaluar el lado izquierdo para producir una variable, evaluar el lado derecho para producir un valor, realizar la asignación, el resultado es el valor asignado.
Así que póngalo junto:
x == (x = y)
Tenemos un operador de comparación. Evalúe el lado izquierdo para producir un valor; obtenemos el valor actual de x
. Evalúe el lado derecho: esa es una asignación, por lo que evaluamos el lado izquierdo para producir una variable, la variable x
, evaluamos el lado derecho, el valor actual de y
, se lo asignamos x
y el resultado es el valor asignado. Luego comparamos el valor original de x
con el valor asignado.
Puedes hacer (x = y) == x
como ejercicio. Nuevamente, recuerde, todas las reglas para evaluar el lado izquierdo suceden antes que todas las reglas para evaluar el lado derecho .
Hubiera esperado que (x = y) fuera evaluado primero, y luego compararía x consigo mismo (3) y devolvería verdadero.
Su expectativa se basa en un conjunto de creencias incorrectas sobre las reglas de Java. Esperemos que ahora tenga las creencias correctas y espere en el futuro cosas verdaderas.
Esta pregunta es diferente del "orden de evaluación de subexpresiones en una expresión Java"
Esta afirmación es falsa. Esa pregunta es totalmente pertinente.
x definitivamente no es una 'subexpresión' aquí.
Esta afirmación también es falsa. Es una subexpresión dos veces en cada ejemplo.
Debe cargarse para la comparación en lugar de ser 'evaluado'.
No tengo idea de lo que esto significa.
Aparentemente todavía tienes muchas creencias falsas. Mi consejo es que leas la especificación hasta que tus creencias falsas sean reemplazadas por creencias verdaderas.
La pregunta es específica de Java y la expresión x == (x = y), a diferencia de los constructos poco prácticos y extravagantes comúnmente diseñados para preguntas difíciles de la entrevista, provino de un proyecto real.
La procedencia de la expresión no es relevante para la pregunta. Las reglas para tales expresiones se describen claramente en la especificación; Léelo!
Se suponía que era un reemplazo de una línea para el lenguaje de comparar y reemplazar
Como ese reemplazo de una línea causó mucha confusión en usted, el lector del código, sugeriría que fue una mala elección. Hacer que el código sea más conciso pero más difícil de entender no es una victoria. Es poco probable que el código sea más rápido.
Por cierto, C # tiene comparar y reemplazar como un método de biblioteca, que puede ser reducido a una instrucción de máquina. Creo que Java no tiene dicho método, ya que no se puede representar en el sistema de tipos Java.