¿Por qué esta declaración if, con una asignación y una verificación de igualdad, se evalúa como falsa?

105

¿Cómo funciona una instrucción if de Java cuando tiene una asignación y una verificación de igualdad OR-d juntas?

public static void test() {
    boolean test1 = true; 
    if (test1 = false || test1 == false) {
        System.out.println("TRUE");
    } else {
        System.out.println("FALSE");
    }       
}

¿Por qué esta impresión es FALSA?

RoHaN
fuente
1
Ejecutar y comprobar. Vea qué valor booleano se imprime si asigna falso y si asigna verdadero. Luego lea cómo funciona el quirófano.
Pratik
2
Me gustaría decir que este código en el modo de depuración da un valor VERDADERO y en el modo de ejecución da un valor FALSO ... ¿Por qué es así ??? ... (Puse mi punto de interrupción en la condición if) ...
CoderNeji
test1=false, test1==falsees false, false || falsees false or falsecuál es false.
Jared Burrows
Sé que no estaba pidiendo un consejo, pero como las respuestas a continuación identifican un problema de precedencia, aquí hay un par de prácticas que me han ayudado a evitar problemas (cuando me apego a estas): (1) siempre use paréntesis cuando no esté al 100% ciertos de precedencia o para facilitar la legibilidad para ayudar a otros desarrolladores. No asuma que otros recordarán las reglas de precedencia para todos los operadores (2) las asignaciones if generalmente deben evitarse para reducir la confusión, excepto para condiciones if muy simples. Hay algunas excepciones comunes (especialmente con comprobaciones simples de E / S, redes, etc.). Solo mis dos centavos.
rimsky
porquetest1 = true
jono

Respuestas:

189

La expresión no se analiza de la forma en que piensa. No es

(test1=false) || (test1 == false)

en cuyo caso el resultado habría sido true, pero

test1 = (false || test1 == false)

El valor de la false || test1 == falseexpresión se calcula primero, y lo es false, porque test1está configurado para trueentrar en el cálculo.

La razón por la que se analiza de esta manera es que la precedencia de ||es menor que la del ==operador, pero mayor que la precedencia del operador de asignación =.

dasblinkenlight
fuente
2
+1 @RohanFernando, tenga en cuenta también que si agrega corchetes alrededor de la tarea de esta manera: ((test1 = false) || test1 == false)el valor general sería true.
Arnon Zilca
1
Por favor, escriba la razón por la que ocurre el análisis. ¿Es por el orden de prioridad de los operadores?
kondu
3
@kondu Esa es una pregunta de seguimiento justa, la edité para agregar un enlace a una tabla de precedencia, que muestra que ==está arriba ||, pero =está abajo ||.
dasblinkenlight
El párrafo final es engañoso, en el sentido de que para entender por qué se elige el segundo análisis sintáctico en lugar del primero, basta con conocer la regla (fácil de recordar) de que la asignación tiene una precedencia menor que cualquier operador de no asignación (aquí ||). La precedencia relativa de ||y ==solo es relevante para mostrar que el análisis sintáctico no es como en test1 = ((false || test1) == false), lo que no creo que nadie esperaría razonablemente (por cierto, la precedencia relativa, o más en general ||, &&tiene una precedencia menor que las relaciones, también es fácil de recuerde, ya que se usa todo el tiempo).
Marc van Leeuwen
1
@MarcvanLeeuwen La precedencia relativa de ||y ==vs ||y =explica por qué esto se comporta de manera diferente al caso (común) de a == b || c == d.
Aaron Dufour
83

Este es un problema de precedencia, básicamente. Está asumiendo que su código es equivalente a:

if ((test1 = false) || (test1 == false))

... pero no lo es. En realidad, es equivalente a:

if (test1 = (false || test1 == false))

... que es equivalente a:

if (test1 = (false || false))

(porque test1es truepara empezar)

... que es equivalente a:

if (test1 = false)

que asigna el valor falsea test1, siendo el resultado de la expresión false.

Consulte el tutorial de Java sobre operadores para obtener una tabla útil de precedencia de operadores.

Jon Skeet
fuente
2

por favor revise la precedencia de los operadores

La expresión test1 = false || test1 == falsese evaluará en el siguiente paso.

PASO: 1- test1 = false || test1 == false // la precedencia de ==es la más alta

PASO: 2- test1 = false || false // El operador ||tiene mayor prioridad

PASO 3- test1 = false

PASO 4- false

Dado que el valor booleano de la expresión se vuelve falso, se está ejecutando la instrucción else.


fuente
-11

(test1 = false || test1 == false)devuelve falso, porque ambos son falsos. (test1 = false || test1 == true)esto es cierto porque uno de ellos es cierto

Guarida
fuente
1
Completamente mal. ¿Por qué respondería con información tan incorrecta días después de que la pregunta haya recibido dos respuestas de alta calidad que describen lo que sucede?
l4mpi
5
Dos respuestas de tan baja calidad no merecen comentarios escritos individualmente. Te das cuenta de que tu respuesta es una tontería, ¿verdad? Si no es así, lea atentamente las dos respuestas de Jon y encienda la luz intermitente.
l4mpi