2010-02-15 14 views
46

Tomemos un ejemplo simple de un objeto Cat. Quiero estar seguro de que el cat "no nulo" es naranja o gris.En Java, ¿cuál es el "orden de operaciones" booleano?

if(cat != null && cat.getColor() == "orange" || cat.getColor() == "grey") { 
//do stuff 
} 

Creo que viene primero, luego el quirófano. Estoy un poco borrosa, sin embargo, así que aquí están mis preguntas:

  1. Puede alguien caminar a través de esta declaración, así que estoy seguro de que consiga lo que sucede?

  2. Además, ¿qué sucede si agrego paréntesis; ¿eso cambia el orden de las operaciones?

  3. ¿Cambiará mi orden de operaciones de un idioma a otro?

+11

Si está confundido, agregue los paréntesis por lo que es obvio. –

+34

Incluso si no es borroso para usted, agregue los paréntesis para que otras personas puedan entenderlo también. –

+2

De Wikipedia en lógica booleana: En tales casos [de ambigüedad], se pueden usar paréntesis para aclarar el orden de las operaciones. Como siempre, las operaciones dentro del par más interno se realizan primero, seguidas por el par siguiente, etc., hasta que se hayan completado todas las operaciones entre paréntesis. Luego, se realizan todas las operaciones fuera de los paréntesis. – Stephano

Respuesta

54

Los Tutoriales de Java tienen una lista que ilustra operator precedence. Los operadores de igualdad se evaluarán primero, luego &&, luego ||. Los paréntesis se evaluarán antes que cualquier otra cosa, por lo que agregarlos puede cambiar el orden. Por lo general, es más o menos lo mismo de un idioma a otro, pero siempre es una buena idea verificarlo dos veces.

Son las pequeñas variaciones en el comportamiento que no espera que puedan ocasionar que pase un día entero depurándose, por lo que es una buena idea colocar los paréntesis en su lugar para asegurarse de cuál será el orden de evaluación .

+1

@VinceEmigh Los operandos no tienen que evaluarse en el mismo orden que la precedencia del operador. Incluso si agrega paréntesis, el programa aún puede ver que 'if (true || (true && s.equals (" ")))' siempre será 'true', por lo que no es necesario evaluar' s.equals ("") 'en absoluto. –

+0

Malo, me acabo de dar cuenta de que estoy muy equivocado. No estaba pensando en la precedencia correctamente. Estaba pensando en términos de evaluación (que se evalúa primero), como en qué operador "posee" los booleanos –

14

fin de Boole de las operaciones (en todos los idiomas, creo):

  1. parens
  2. NO
  3. Y
  4. O

Así que su lógica anterior es equivalente a:

(cat != null && cat.getColor() == "orange") || cat.getColor() == "grey" 
4

En primer lugar, si su declaración contiene tres expresiones principales:

  1. cat = null
  2. cat.getColor() == "naranja"
  3. cat.getColor() == "grises! "

La primera expresión simplemente verifica si cat no es nulo. Es necesario, de lo contrario, la segunda expresión se ejecutará y dará como resultado un NPE(null pointer excpetion). Es por eso que el uso de & & entre la primera y la segunda expresión. Cuando usa &&, si la primera expresión se evalúa como falsa, la segunda expresión nunca se ejecuta. Finalmente, verifica si el color del gato es gris.

Por último destacar que su sentencia if es todavía mal porque si el gato es nula, la tercera expresión es todavía ejecutados y por lo tanto se obtiene una nula puntero excepción.

La forma correcta de hacerlo es:

if(cat != null && (cat.getColor() == "orange" || cat.getColor() == "grey")) { 
//do stuff 
} 

comprobar el orden de paréntesis.

8

la expresión es básicamente idéntica a:

if ((cat != null && cat.getColor() == "orange") || cat.getColor() == "grey") { 
    ... 
} 

El orden de precedencia aquí es que Y (&&) tiene mayor precedencia que OR (||).

También debe saber que el uso de == para probar la igualdad de cadenas a veces funciona en Java, pero no es cómo debe hacerlo. Que debe hacer:

if (cat != null && ("orange".equals(cat.getColor()) || "grey".equals(cat.getColor()))) { 
    ... 
} 

es decir, usar los métodos para equals()String comparación, no == que simplemente se hace referencia igualdad. La igualdad de referencia para cadenas puede ser engañosa. Por ejemplo:

String a = new String("hello"); 
String b = new String("hello"); 
System.out.println(a == b); // false 
+0

Creo que te falta un paren en ese primer ejemplo, o estoy demasiado cansado. –

+0

@Robert: estaban en mal estado. Reparado, gracias. – cletus

3

&& definitivamente se evalúa antes de ||. Pero veo que estás haciendo cat.getColor() == "orange" que podría darte un resultado inesperado. Es posible que desee a este lugar:

if(cat != null && ("orange".equals(cat.getColor()) || "grey".equals(cat.getColor()))) { 
    //do stuff 
} 
-2

orden de la operación no es lo que necesita, necesita álgebra de Boole, esto incluye funciones booleanas. Maxterms/minterms, código Gray, tablas de Karnaugh, diodos, transistores, compuertas lógicas, multiplexores, bitadders, flip flops ... Lo que quiere es implementar una "lógica" booleana en computadoras o máquinas virtuales. Con el "orden de las operaciones", puede referir algo acerca de la física, como la gestión de retrasos en las compuertas lógicas (O, si) intervalos de nanosegundos.

Cuestiones relacionadas