2010-02-15 15 views
46

Prenons un exemple simple d'un objet Cat. Je veux être sûr que le "non nul" cat est orange ou gris.En Java, quels sont les "ordres d'opérations" booléens?

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

Je crois ET vient en premier, puis le OU. Je suis bien un peu floue, alors voici mes questions:

  1. Quelqu'un peut-il me promener à travers cette déclaration, donc je suis sûr que je reçois ce qui se passe?

  2. En outre, que se passe-t-il si j'ajoute des parenthèses; Est-ce que cela change l'ordre des opérations?

  3. Est-ce que mon ordre des opérations va changer de langue à langue?

+11

Si vous êtes du tout flou, ajoutez les parenthèses, c'est évident. –

+34

Même si ce n'est pas flou pour vous, ajoutez les parenthèses afin que les autres puissent le comprendre aussi. –

+2

De wikipedia sur la logique booléenne: Dans de tels cas [d'ambiguïté], des parenthèses peuvent être utilisées pour clarifier l'ordre des opérations. Comme toujours, les opérations au sein de la paire la plus interne sont effectuées en premier, suivies de la sortie de la paire suivante, etc., jusqu'à ce que toutes les opérations entre parenthèses soient terminées. Ensuite, toutes les opérations en dehors des parenthèses sont effectuées. – Stephano

Répondre

54

Les didacticiels Java ont une liste illustrant operator precedence. Les opérateurs d'égalité seront évalués en premier, puis &&, puis ||. Les parenthèses seront évaluées avant toute autre chose, donc les ajouter peut changer l'ordre. C'est généralement la même chose d'une langue à l'autre, mais c'est toujours une bonne idée de vérifier. Ce sont les petites variations de comportement que vous n'attendez pas et qui vous obligent à passer une journée de débogage. Il est donc conseillé de mettre les parenthèses en place afin de vous assurer de l'ordre d'évaluation. .

+1

@VinceEmigh Les opérandes n'ont pas à être évalués dans le même ordre que la priorité de l'opérateur. Même si vous ajoutez des parenthèses, le programme peut toujours voir que 'if (true || (true && s.equals (" "))) sera toujours' true', donc il n'a pas besoin d'évaluer 's.equals ("") 'du tout. –

+0

Mon diable, je viens de réaliser que je me suis fortement trompé. Je ne pensais pas à la préséance correctement. Je pensais en termes d'évaluation (qui est évaluée en premier), comme dans quel opérateur "possède" les booléens –

14

pour Boolean des opérations (dans toutes les langues, je crois):

  1. parens
  2. PAS
  3. ET
  4. OU

donc votre logique ci-dessus est équivalente à:

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

D'abord, votre instruction if contient trois expressions principales:

  1. cat = null
  2. cat.getColor() == "orange"
  3. cat.getColor() == « gris! "

La première expression vérifie simplement si cat n'est pas nul. C'est nécessaire sinon la seconde expression sera exécutée et donnera NPE(null pointer excpetion). C'est pourquoi l'utilisation de & & entre la première et la seconde expression. Lorsque vous utilisez &&, si la première expression est évaluée à false, la seconde expression n'est jamais exécutée. Enfin, vous vérifiez si la couleur du chat est gris.

Notons enfin que votre instruction if est encore mal parce que si le chat est nulle, la troisième expression est encore exécutée et, par conséquent, vous obtenez une exception de pointeur null.

La bonne façon de le faire est la suivante:

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

Vérifiez l'ordre de parenthèses.

8

L'expression est fondamentalement identique à:

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

L'ordre de priorité est ici que ET (&&) a priorité supérieure ou (||).

Vous devez également savoir que l'utilisation de == pour tester l'égalité des chaînes sera parfois fonctionne en Java mais ce n'est pas comme cela que vous devriez le faire. Vous devriez faire:

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

-à-dire utiliser les méthodes equals() pour String comparaison, non == qui ne fonctionne tout simplement l'égalité de référence. L'égalité de référence pour les chaînes peut être trompeuse. Par exemple:

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

Je pense qu'il vous manque un parent dans ce premier exemple, ou je suis juste trop fatigué. –

+0

@Robert: ils ont été foirés. Fixe, merci. – cletus

3

Yeah && est définitivement évalué avant ||. Mais je vois que vous faites cat.getColor() == "orange" qui pourrait vous donner un résultat inattendu. Vous voudrez peut-être à ce lieu:

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

Ordre de fonctionnement est pas ce que vous avez besoin, vous avez besoin d'algèbre booléenne, cela inclut des fonctions booléennes. Maxterms/minterms, code Gray, tables de Karnaugh, diodes, transistors, portes logiques, multiplexeurs, bitadders, flip flops ... Ce que vous voulez, c'est implémenter la "booléenne" sur les ordinateurs ou les machines virtuelles. Avec "l'ordre des opérations" vous pouvez vous référer à quelque chose à propos de la physique comme la gestion des retards sur les portes logiques (OU, si) des intervalles de nanosecondes?