A door with rules#
A venue has a door and a person checking people in. The rules are: you must be 18 or over and have a ticket, unless you are on the guest list, in which case the ticket does not matter. Nobody at that door is confused by those rules, and nobody needs a lesson in logic to apply them.
Every if in Java is that door. It lets the code through or it does not, depending on one value that is either true or false. That kind of value is a boolean. This guide is about how booleans are built, how Java combines them, and the two statements that act on them: if and switch.
Comparisons produce true or false#
A comparison is a question with a yes-or-no answer, and in Java the answer is a boolean:
public class Compare {
public static void main(String[] args) {
int score = 72;
System.out.println(score >= 70);
System.out.println(score == 70);
System.out.println(score != 70);
boolean passed = score >= 70;
System.out.println("passed: " + passed);
}
}
true
false
true
passed: true
| Operator | Say it out loud as |
|---|---|
== | is equal to |
!= | is not equal to |
< <= | is less than, is at most |
> >= | is greater than, is at least |
One equals sign is not a comparison. = means “store this”, and == means “are these equal?”. Java catches the mix-up for you:
public class Assign {
public static void main(String[] args) {
int n = 5;
if (n = 5) {
System.out.println("five");
}
}
}
Assign.java:4: error: incompatible types: int cannot be converted to boolean
if (n = 5) {
^
1 error
n = 5 stores 5 and produces the number 5, and an if needs a boolean. Some languages accept this line and quietly always take the branch. Java refuses to compile it, which is a favour.
AND, OR and NOT#
Three operators combine booleans. Each one matches a word you already use.
| Operator | Word | True when… |
|---|---|---|
&& | and | both sides are true |
|| | or | at least one side is true |
! | not | the value is false (it flips it) |
public class Door {
public static void main(String[] args) {
int age = 19;
boolean hasTicket = false;
boolean onGuestList = true;
System.out.println(age >= 18 && hasTicket);
System.out.println(hasTicket || onGuestList);
System.out.println(!hasTicket);
System.out.println(age >= 18 && (hasTicket || onGuestList));
}
}
false
true
true
true
The last line is the door rule from the start: 18 or over, and either a ticket or a place on the guest list. The brackets matter. && binds more tightly than ||, the way * binds more tightly than +, so without brackets Java would read it as “(18 and ticket) or guest list”, which is a different rule.
A truth table lists every combination. For two values there are four rows:
a | b | a && b | a || b |
|---|---|---|---|
| true | true | true | true |
| true | false | false | true |
| false | true | false | true |
| false | false | false | false |
AND is true in one row out of four. OR is false in one row out of four.
The half Java never looks at#
If the person at the door sees you are 15, they do not bother asking for your ticket. The answer is already no.
Java does the same, and it is called short-circuit evaluation: with &&, a false left side decides everything, so the right side is skipped; with ||, a true left side decides everything, so the right side is skipped.
public class Guard {
static boolean loud(String name, boolean value) {
System.out.print("[" + name + "] ");
return value;
}
public static void main(String[] args) {
int count = 0;
if (count != 0 && 100 / count > 5) {
System.out.println("big");
}
System.out.println("no crash");
boolean a = loud("left", false) && loud("right", true);
System.out.println(a);
boolean b = loud("left", true) || loud("right", false);
System.out.println(b);
}
}
no crash
[left] false
[left] true
Two things are happening. In the first if, count != 0 is false, so 100 / count is never evaluated and nothing divides by zero. Putting the safety check on the left is the standard way to guard a risky expression.
The loud method prints its name whenever it runs, so you can see which sides were evaluated. Each time, only [left] appears. The right-hand call was never made. If that call had done something important, such as counting or saving, it would not have happened.
Flipping a condition: De Morgan's laws#
Sometimes you have a condition and need its opposite. Putting ! in front of the whole thing works, but it can be hard to read. De Morgan's laws are the rules for pushing the ! inside:
| This | means the same as | In words |
|---|---|---|
!(a && b) | !a || !b | not both = at least one is not |
!(a || b) | !a && !b | not either = neither |
The recipe: flip each part, and swap && with ||. Flipping a comparison means < becomes >=, > becomes <=, and == becomes !=.
public class Morgan {
public static void main(String[] args) {
for (int n = 0; n <= 12; n += 6) {
boolean outside1 = !(n >= 1 && n <= 10);
boolean outside2 = n < 1 || n > 10;
System.out.println(n + ": " + outside1 + " " + outside2);
}
}
}
0: true true
6: false false
12: true true
“Not between 1 and 10” becomes “less than 1 or more than 10”, and the two columns agree for every value tested. The common mistake is to write n < 1 && n > 10, which asks for a number that is both too small and too big at once. No such number exists, so that condition is always false.
if-else chains#
An if can have an else, and an else can hold another if. That makes a chain, and Java checks it from the top, stopping at the first true condition.
public class Grade {
public static void main(String[] args) {
int score = 85;
if (score >= 90) {
System.out.println("A");
} else if (score >= 80) {
System.out.println("B");
} else if (score >= 70) {
System.out.println("C");
} else {
System.out.println("below C");
}
}
}
B
85 is also at least 70, but the C branch never runs because the chain already stopped at B. That is why the order matters: put the strictest test first. Written the other way round, starting with score >= 70, every passing score would come out as C.
Braces, the { } around a body, are required when a body has more than one statement. Without them, only the single next statement belongs to the if. Style guides ask for them every time anyway, and the next section shows why.
The else that joined the wrong if#
Read this and decide what it prints before you look at the output. The indentation is deliberately misleading.
public class Dangle {
public static void main(String[] args) {
int temp = 30;
if (temp > 50)
if (temp > 80)
System.out.println("hot");
else
System.out.println("mild");
System.out.println("done");
}
}
done
Only done. It looks as if else pairs with if (temp > 50), so you might expect mild. But Java ignores indentation completely. An else always belongs to the nearest if that does not already have one, which here is if (temp > 80). Since temp > 50 is false, the inner if and its else are skipped together.
Braces make the pairing impossible to misread, which is the real reason to use them every time.
switch: one value, many tracks#
A railway switch sends a train down one of several tracks. A switch statement takes one value and jumps to the case label that matches it.
public class Menu {
public static void main(String[] args) {
char choice = 'b';
switch (choice) {
case 'a':
System.out.println("New game");
break;
case 'b':
System.out.println("Load game");
break;
case 'q':
System.out.println("Quit");
break;
default:
System.out.println("Unknown option");
}
String day = "sat";
switch (day) {
case "sat":
case "sun":
System.out.println("weekend");
break;
default:
System.out.println("weekday");
}
}
}
Load game
weekend
The pieces:
caselabels are the tracks. Each must be a constant known when the program is compiled: a literal like'a',3or"sat", or afinalconstant. Two labels with the same value will not compile.breaksays “this case is finished” and jumps out of the switch.defaultis the “none of these” track, like the finalelseof a chain. It is optional.
The second switch shows two labels sharing one body: stacking case "sat": and case "sun": means either one leads to weekend. Switching on a String has been allowed since Java 7, and it compares the text, the same way equals does.
Fall-through: the switch that keeps going#
Leave out the break statements and watch what happens:
public class Fall {
public static void main(String[] args) {
int level = 2;
switch (level) {
case 1: System.out.println("level 1");
case 2: System.out.println("level 2");
case 3: System.out.println("level 3");
default: System.out.println("default");
}
}
}
level 2
level 3
default
level is 2, so execution starts at case 2, and then simply keeps going through every line below it, including default. The labels are only entry points. Nothing tells Java to stop except break or the end of the switch. This is called fall-through.
Occasionally it is exactly what you want, as with the stacked weekend labels. Most of the time it is a forgotten break.
One more limit. A classic switch works on int, char, short, byte, String and enums. It will not accept a double, long or boolean:
public class NoDouble {
public static void main(String[] args) {
double price = 2.5;
switch (price) {
case 2.5: System.out.println("yes"); break;
}
}
}
NoDouble.java:4: error: selector type double is not allowed
switch (price) {
^
1 error
Matching decimals exactly is unreliable, which is why Java does not allow it. Use an if chain for doubles and for ranges.
if or switch?#
| Situation | Use |
|---|---|
| one variable compared for equality against several fixed values | switch reads cleanly |
ranges, such as score >= 90 | if chain |
| several different variables | if chain |
a double or a boolean | if |
Any switch can be rewritten as an if chain. Only a chain that compares one variable with == against constants can be rewritten as a switch.
An else belongs to the nearest if, a case keeps running until it hits break, and && and || skip the right side once the left side has decided.
Where these go wrong#
=instead of==. Java refuses it in anif: int cannot be converted to boolean.- Trusting indentation. Java does not read it. Use braces.
- Ordering an if-else chain loosest-first. The first true branch wins, so the strictest test must come first.
- Forgetting
break. The next case runs too, and the one after that. - Writing a range as
n < 1 && n > 10. That is never true. Outside a range is||. - Negating half a condition.
!(a && b)is!a || !b, not!a && !b. - Putting the risky check on the left.
100 / count > 5 && count != 0divides first. Guard first, then compute. - Switching on a double. Not allowed. Use
if.
Test yourself in the free Kestrel Exams app
Topic-selectable practice — offline, no ads, no account.
Practice if, switch and boolean logic →Frequently asked questions#
What is short-circuit evaluation in Java?
With && and ||, Java stops evaluating as soon as the answer is certain. If the left side of && is false, the whole expression is false, so the right side is never evaluated. If the left side of || is true, the whole expression is true, so the right side is skipped. This is why a check like count != 0 && 100 / count > 5 never divides by zero.
What are De Morgan's laws in Java?
They are the rules for moving a ! inside brackets. !(a && b) is the same as !a || !b, and !(a || b) is the same as !a && !b. Flip each part and swap && for ||. For example, !(n >= 1 && n <= 10) becomes n < 1 || n > 10.
Which if does an else belong to in Java?
An else always belongs to the nearest preceding if that does not already have an else, regardless of how the code is indented. Java ignores indentation. Using braces around every if body makes the pairing unmistakable.
What happens if you forget break in a Java switch?
Execution falls through: after the matching case runs, Java continues into the next case, and the one after it, until it reaches a break or the end of the switch. The case labels are only entry points. Sometimes this is used on purpose to let several labels share one body.
Can you use a switch statement with a String or a double in Java?
A String, yes, since Java 7: the case labels are string literals and they are compared by their text. A double, no: a classic switch does not accept double, float, long or boolean, and javac rejects it. Use an if-else chain for decimals and ranges.
What is the difference between = and == in Java?
= assigns a value to a variable. == compares two values and produces true or false. Writing if (n = 5) in Java does not compile, because n = 5 produces an int and an if needs a boolean.
Something here not clear? A topic you wish we covered? Tell us. We read every message, and a request is the fastest way to get a guide written — several of these exist because somebody asked.
