71

Let's take a simple example of an object Cat. I want to be sure the "not null" cat is either orange or grey.

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

I believe AND comes first, then the OR. I'm kinda fuzzy though, so here are my questions:

  1. Can someone walk me through this statement so I'm sure I get what happens?

  2. Also, what happens if I add parentheses; does that change the order of operations?

  3. Will my order of operations change from language to language?

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Stephano
  • 5,716
  • 7
  • 41
  • 57
  • 12
    If you're at all fuzzy, add the parentheses so it's obvious. – Anon. Feb 15 '10 at 02:02
  • 41
    Even if it's not fuzzy to you, add the parentheses so other people can understand it too. – Brendan Long Feb 15 '10 at 02:05
  • 3
    From wikipedia on boolean logic: In such cases [of ambiguity], parentheses may be used to clarify the order of operations. As always, the operations within the innermost pair is performed first, followed by the next pair out, etc., until all operations within parentheses have been completed. Then any operations outside the parentheses are performed. – Stephano Feb 15 '10 at 02:15
  • 1
    probably one of the many StackOverFlow Trolls. Don't worry about it. I think your answer is fine too. – davidahines May 05 '11 at 16:16
  • 3
    You most probably want to use cat.getColor().equals("orange") and not '=='. – Albert Hendriks Dec 16 '17 at 20:49

6 Answers6

73

The Java Tutorials has a list illustrating operator precedence. The equality operators will be evaluated first, then &&, then ||. Parentheses will be evaluated before anything else, so adding them can change the order. This is usually pretty much the same from language to language, but it's always a good idea to double check.

It's the small variations in behavior that you're not expecting that can cause you to spend an entire day debugging, so it's a good idea to put the parentheses in place so you're sure what the order of evaluation will be.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
  • 1
    @VinceEmigh The operands don't have to be evaluated in the same order as operator precedence. Even if you add parentheses, the program can still see that `if(true || (true && s.equals("")))` will always be `true`, so it doesn't need to evaluate `s.equals("")` at all. – Bill the Lizard Oct 06 '15 at 02:04
  • My bad, I just realized I'm strongly mistaken. I wasn't thinking of precedence correctly. I was thinking in terms of evaluation (which gets evaluated first), as in which operator "owns" the booleans – Vince Oct 06 '15 at 02:59
25

Boolean order of operations (in all languages I believe):

  1. parens
  2. NOT
  3. AND
  4. OR

So your logic above is equivalent to:

(cat != null && cat.getColor() == "orange") || cat.getColor() == "grey"
Trey Hunner
  • 10,975
  • 4
  • 55
  • 114
8

The expression is basically identical to:

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

The order of precedence here is that AND (&&) has higher precedence than OR (||).

You should also know that using == to test for String equality will sometimes work in Java but it is not how you should do it. You should do:

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

ie use the equals() methods for String comparison, not == which simply does reference equality. Reference equality for strings can be misleading. For example:

String a = new String("hello");
String b = new String("hello");
System.out.println(a == b); // false
cletus
  • 616,129
  • 168
  • 910
  • 942
6

First, your if statement contains three main expressions:

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

The first expression simply checks whether cat is not null. Its necessary otherwise the the second expression will get executed and will result in a NPE(null pointer excpetion). That's why the use of && between the first and second expression. When you use &&, if the first expression evaluates to false the second expression is never executed. Finally you check whether the cat's color is grey.

Finally note that your if statement is still wrong because if cat is null, the third expression is still executed and hence you get a null pointer exception.

The right way of doing it is:

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

Check the order of parenthesis.

Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
Suraj Chandran
  • 24,433
  • 12
  • 63
  • 94
5

Yeah && is definitely evaluated before ||. But I see you are doing cat.getColor() == "orange" which might give you unexpected result. You may want to this instead :

if(cat != null && ("orange".equals(cat.getColor()) || "grey".equals(cat.getColor()))) {
    //do stuff
}
fastcodejava
  • 39,895
  • 28
  • 133
  • 186
-4

Order of Operation is not what you need, you need boolean algebra, this includes boolean functions. Maxterms/minterms, Gray code, Karnaugh tables, diodes,transistors, logic gates, multiplexers, bitadders, flip flops... What you want is to implement boolean "logic" on computers or virtual machines. With "order of operations" you may refer something about physics like managing delays on logic gates (OR, if) nanoseconds intervals?