web-dev-qa-db-fra.com

En Java, quel est "l'ordre des opérations" booléen?

Prenons un exemple simple d'un objet Cat. Je veux être sûr que le "non nul" cat est orange ou gris.

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

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

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

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

  3. Mon ordre des opérations changera-t-il d'une langue à l'autre?

55
Stephano

Le Java Tutorials a une liste illustrant priorité de l'opérateur . Les opérateurs d'égalité seront évalués en premier, puis &&, puis ||. Les parenthèses seront évaluées avant toute autre chose, donc leur ajout peut changer l'ordre. C'est généralement à peu près la même d'une langue à l'autre, mais c'est toujours une bonne idée de vérifier.

Ce sont les petites variations de comportement auxquelles vous ne vous attendez pas qui peuvent vous amener à passer une journée entière à déboguer.C'est donc une bonne idée de mettre les parenthèses en place afin d'être sûr de l'ordre des évaluations.

58
Bill the Lizard

Ordre des opérations booléen (dans toutes les langues je crois):

  1. parens
  2. NE PAS
  3. ET
  4. OR

Donc, votre logique ci-dessus équivaut à:

(cat != null && cat.getColor() == "orange") || cat.getColor() == "grey"
16
Trey Hunner

L'expression est fondamentalement identique à:

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

L'ordre de priorité ici est que ET (&&) A une priorité plus élevée que OR (||)).

Vous devez également savoir que l'utilisation de == Pour tester l'égalité des chaînes parfois fonctionnera dans 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()))) {
  ...
}

c'est-à-dire utiliser les méthodes equals() pour la comparaison String, pas == qui fait simplement référence à l'égalité. 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
8
cletus

Oui, && Est définitivement évalué avant ||. Mais je vois que vous faites cat.getColor() == "orange" ce qui pourrait vous donner un résultat inattendu. Vous pouvez le faire à la place:

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

Tout d'abord, votre instruction if contient trois expressions principales:

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

La première expression vérifie simplement si cat n'est pas nul. Son nécessaire sinon la deuxième expression sera exécutée et se traduira par une NPE(null pointer excpetion). C'est pourquoi l'utilisation de && entre la première et la deuxième expression. Lorsque vous utilisez &&, si la première expression est fausse, la deuxième expression n'est jamais exécutée. Enfin, vous vérifiez si la couleur du chat est grise.

Notez enfin que votre instruction if est toujours incorrecte car si cat est nul, la troisième expression est toujours exécutée et donc vous obtenez exception de pointeur nul.

La bonne façon de procéder est:

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

Vérifiez l'ordre des parenthèses.

4
Suraj Chandran