Java Logical Operators
Table of Contents + β
In the last lesson you learned about Java relational operators. Real rules like βlet the user in if they are over 18 and they agreed to the termsβ need two checks joined together. Java gives you logical operators for exactly this.
π€ Why combine conditions?
A single comparison can ask only one thing. But most real decisions depend on several things at once:
- A login. Username correct and password correct.
- A discount. Cart total over 1000 or the person is a member.
- A warning banner. Show it when the user is not logged in.
Logical operators are the glue. They take the true/false that comparisons hand you and fold them into one final answer your if acts on.
π The three logical operators
Java has three logical operators. Here is a quick map, then we take them one at a time.
| Operator | Name | True when⦠|
|---|---|---|
| && | AND | Both sides are true |
| || | OR | At least one side is true |
| ! | NOT | Flips true to false and false to true |
One thing to keep in mind: && and || work on two values (left and right). The ! operator works on just one.
β The AND operator (&&)
The AND operator &&:
- Is true only when both sides are true.
- Is false the moment any one side is false.
- Acts like a door with two locks: you need both keys, or it stays shut.
This code checks an age and a terms agreement, then prints whether both are satisfied.
int age = 20;boolean agreedToTerms = true;System.out.println(age >= 18 && agreedToTerms);Reading it step by step:
age >= 18istrue(20 is at least 18).agreedToTermsistrue.- Both true, so
&&givestrue. The user gets in.
Output
trueNow flip one value. Suppose the user did not agree to the terms.
int age = 20;boolean agreedToTerms = false;System.out.println(age >= 18 && agreedToTerms);The age check still passes, but agreedToTerms is now false. With &&, one false side sinks the whole result. The login is blocked.
Output
falseπ΅ The OR operator (||)
The OR operator ||:
- Is true when at least one side is true.
- Is false only when both sides are false, so it is easy to satisfy.
- Acts like a club door that opens with either a ticket or a membership card.
This code checks the cart total and the membership, then prints whether the discount applies.
double cartTotal = 500;boolean isMember = true;System.out.println(cartTotal > 1000 || isMember);Reading it step by step:
cartTotal > 1000isfalse(500 is not over 1000).isMemberistrue.- One side is true, and for
||that is enough. So the result istrue. The discount applies.
Output
true|| gives false only when both sides fail at once: a small cart and a non-member.
π« The NOT operator (!)
The NOT operator !:
- Works on a single value, not two.
- Flips it: true becomes false, false becomes true.
- Sits in front of the value, like
!isLoggedIn, read as βnot logged inβ.
This code checks whether someone is logged in, then flips that to decide if the warning should show.
boolean isLoggedIn = false;System.out.println(!isLoggedIn);Reading it step by step:
isLoggedInholdsfalse.- The
!flips thatfalseintotrue. - So
!isLoggedInistrue, your cue to show the βplease log inβ warning.
Output
trueCaution
! is one tiny character, so it is easy to miss. When a condition acts the opposite of what you expect, check whether a ! snuck in or went missing.
π The truth tables
A truth table lists every combination of inputs and shows the answer for each. Here is one per operator.
For AND &&, both must be true, so the answer is true in only one row.
| A | B | A && B |
|---|---|---|
| true | true | true |
| true | false | false |
| false | true | false |
| false | false | false |
For OR ||, any one true is enough, so the answer is false in only one row.
| A | B | A || B |
|---|---|---|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
And NOT ! is the simplest table: one input, flipped.
| A | !A |
|---|---|
| true | false |
| false | true |
Quick memory trick: for && the only true is both-true; for || the only false is both-false.
β‘ Short-circuit evaluation
Short-circuit evaluation means Java reads left to right and stops the moment the answer is certain:
- With
&&, a false left side already settles the result as false, so Java skips the right side. - With
||, a true left side already settles it as true, so Java skips the right side. - This is faster (an expensive call on the right gets skipped) and safer (a guard on the left protects a risky check on the right).
That last point is the big one. This code shows the classic null-guard on a name that is null.
String name = null;if (name != null && name.length() > 0) { System.out.println("Name is set");} else { System.out.println("No name");}Reading it step by step:
- The left side
name != nullruns first and isfalse. - A false left side settles the
&&, so Java stops there. - It never runs
name.length(), which would crash with aNullPointerExceptionon anullvalue.
Output
No nameOrder matters: the guard name != null sits on the left on purpose so it runs first and protects the call on the right.
|| has its own safe pattern: it can short-circuit out early when something is already true.
boolean isAdmin = true;if (isAdmin || hasExpensivePermissionCheck()) { System.out.println("Access granted");}Since isAdmin is true, the || is already settled. So Java skips hasExpensivePermissionCheck() entirely, saving real time when the cheap reason is enough.
π The difference between && and &
Java also has a single & and a single |. For booleans:
- They do not short-circuit; they always check both sides.
- That mostly does nothing, but it bites when the right side has a guard depending on the left.
See what goes wrong here.
String name = null;// β Single & checks BOTH sides, so length() still runs and crashesif (name != null & name.length() > 0) { System.out.println("Name is set");}Even though name != null is false, the single & still runs name.length() and crashes. The double && would have skipped it. So for conditions, always use && and ||. The single & and | are for bit-level math, a different topic.
β Combining conditions with brackets
You can chain more than two checks. But once you mix && and || on one line, use brackets to keep the grouping clear:
&&binds tighter than||, like multiply binds tighter than add in maths.- Without brackets, the
&&parts group first, which is not always what you meant. - Brackets remove all doubt.
This range check uses brackets to say βthe score is between 0 and 100, and the user is activeβ.
int score = 85;boolean isActive = true;if ((score >= 0 && score <= 100) && isActive) { System.out.println("Valid active score");}The brackets group the range test as one idea, then join it with isActive. Reading it back: a valid range, and the user is active.
Output
Valid active scoreHere brackets really change the meaning: free shipping for a large order, or for a premium member in a supported country.
double total = 200;boolean isPremium = true;boolean inSupportedCountry = true;if (total > 500 || (isPremium && inSupportedCountry)) { System.out.println("Free shipping");}The brackets keep isPremium && inSupportedCountry together as one reason. Then || offers two paths: a big order, or a premium member in a supported country. The order is only 200, so the first path fails, but the second passes. Shipping is free.
Output
Free shippingTip
Even when brackets are not strictly required, adding them makes mixed logic easier to read. Your future self will thank you when revisiting the code months later.
β οΈ Common Mistakes
A few slip-ups trip up almost everyone at first.
Using single & or | for conditions. These do not short-circuit, so a guard on the left will not protect the right side. Use the double forms.
// β Avoid: single & runs both sides, so a null guard does not protect you// if (user != null & user.isActive()) ...
// β
Good: double && short-circuits and stops at the false left sideif (user != null && user.isActive()) { System.out.println("Active user");}Getting AND and OR backwards. AND needs everything true. OR needs just one true. Swapping them quietly changes your whole rule.
// β Avoid: OR lets anyone over 18 in, even without agreeing// if (age >= 18 || agreedToTerms) ...
// β
Good: AND requires both to be trueif (age >= 18 && agreedToTerms) { System.out.println("Welcome");}Forgetting the safe order with &&. The guard check has to come first. Put the risky check after it, so short-circuiting can protect it.
// β Avoid: length() runs before the null check, so this can crash// if (name.length() > 0 && name != null) ...
// β
Good: the null guard is on the left and runs firstif (name != null && name.length() > 0) { System.out.println("Name is set");}β Best Practices
A few habits keep your logic clean and safe:
- Use
&&and||, not&and|. The double forms are built for combining conditions, and they short-circuit. - Put guard checks first. With
&&, anullcheck or a zero check on the left keeps the right side safe to run. - Use brackets for mixed logic. When
&&and||appear together, brackets like(a && b) || cspell out exactly what you mean. - Read conditions out loud. If βover 18 and agreedβ matches your rule, you picked the right operator. If it sounds wrong spoken, the code is probably wrong too.
- Avoid double negatives.
!isNotReadyis hard to read. Name the variable for the positive case, likeisReady, and life gets simpler.
π§© What Youβve Learned
Quick recap of the key points:
- β
Logical operators combine boolean values into one final
trueorfalse. - β
&&(AND) is true only when both sides are true. - β
||(OR) is true when at least one side is true. - β
!(NOT) flips a single boolean to its opposite. - β
Short-circuit evaluation stops as soon as the answer is known, which also protects risky checks placed on the right of
&&. - β
Single
&and|do not short-circuit, so stick with the double forms for conditions. - β
Brackets make mixed
&&and||logic clear and predictable.
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
When is A && B true?
Why: AND (&&) is true only when both sides are true. If either is false, the result is false.
- 2
When is A || B true?
Why: OR (||) is true when at least one side is true. It is only false when both are false.
- 3
What does the ! operator do?
Why: NOT (!) reverses a boolean, turning true into false and false into true.
- 4
Why does name != null && name.length() > 0 not crash when name is null?
Why: With &&, if the left side is false, Java skips the right side, so length() is never called on null.
π Whatβs Next?
You can now build rich conditions. Next we look at operators that work on a single value. They let you increment, decrement, and flip a sign with one short symbol.