2.5 - Compound Boolean Expressions
You can combine boolean expressions using logical operators:
! // not && // and || // or
!aistrueifaisfalse, and vice versa.
a && bistrueonly if bothaandbaretrue.
a || bistrueifais true,bis true, or both.
Here’s every case in a truth table:
a | b | !a | a && b | a || b |
true | true | false | true | true |
true | false | false | false | true |
false | true | true | false | true |
false | false | true | false | false |
Precedence order for these:
! first, then &&, then ||.So
true || false && false is true: the && goes first (false && false is false), then true || false is true. Use parentheses when you want a different order: (true || false) && false is false.Relational operators like
< and == are evaluated before && and ||, so x > 0 && x < 10 works without extra parentheses. But ! comes before relational operators, so to negate a comparison you need parentheses: write !(x > 5), not !x > 5 (that won’t compile when x is an int).int age = 15; boolean hasPermit = true; boolean canDrive = age >= 16 || age >= 15 && hasPermit; // && goes first, so this means age >= 16 || (age >= 15 && hasPermit) // age >= 16 is false // age >= 15 && hasPermit is true && true, which is true // false || true is true System.out.println(canDrive); // true
boolean canRide = age >= 12 && height >= 48; boolean isEligible = hasPermission || isAdult; boolean isNotReady = !isFinished;
Short-Circuit Evaluation
Java uses short-circuit evaluation for
&& and ||. That means if Java can already figure out the result just from the first expression, it won’t even bother evaluating the second one.// if age >= 16 is false, Java never checks hasLicense, since && already fails if (age >= 16 && hasLicense) { System.out.println("Can drive."); } // if isMember is true, Java never checks hasCoupon, since || already succeeds if (isMember || hasCoupon) { System.out.println("You get a discount."); }
Short-circuiting is useful for avoiding errors. Put the safety check first, and Java won’t run the risky part when the check fails:
int count = 0; int total = 50; if (count != 0 && total / count > 10) { System.out.println("Average is over 10."); } System.out.println("Done."); // prints only: Done. // count != 0 is false, so total / count never runs (no ArithmeticException)
Flip the order to
total / count > 10 && count != 0 and the program crashes with an ArithmeticException, because the division runs first.