Skip to content

Java Decision Making

Decision making structures allow your program to choose different paths of execution based on whether certain conditions are true or false. Java provides several statements for this:

  • if statements (including if-else and if-else if-else)
  • switch statements (including traditional switch and modern switch expressions)

The simplest decision-making statement. It executes a block of code only if a specified boolean expression evaluates to true.

if (boolean_expression) {
// Statements to execute if the expression is true
}
// Code here executes regardless

If the boolean_expression is true, the code inside the curly braces {} is executed. If it’s false, that block is skipped, and execution continues after the if statement’s closing brace.

public class BasicIfExample {
public static void main(String[] args) {
int score = 75;
if (score >= 60) {
System.out.println("Congratulations, you passed!");
}
System.out.println("Execution continues...");
}
}

Output:

Congratulations, you passed!
Execution continues...

An if statement can be followed by an optional else block. The else block executes only when the if statement’s boolean expression is false.

if (boolean_expression) {
// Executes when the boolean expression is true
} else {
// Executes when the boolean expression is false
}
public class IfElseExample {
public static void main(String[] args) {
int temperature = 15;
if (temperature > 25) {
System.out.println("It's a hot day!");
} else {
System.out.println("It's not too hot today.");
}
}
}

Output:

It's not too hot today.

Used to check multiple conditions sequentially. The first condition that evaluates to true has its corresponding block executed, and the rest of the else if and else blocks are skipped. The final else block (optional) executes if none of the preceding if or else if conditions are true.

Key points:

  • An if can have zero or more else if blocks.
  • An if can have zero or one else block, which must come after all else if blocks.
  • As soon as an if or else if condition is met, its block executes, and the entire structure is exited.
if (condition_1) {
// Executes if condition_1 is true
} else if (condition_2) {
// Executes if condition_1 is false and condition_2 is true
} else if (condition_3) {
// Executes if conditions 1 and 2 are false, and condition_3 is true
} else {
// Executes if none of the above conditions are true (optional)
}
public class GradingExample {
public static void main(String[] args) {
int score = 85;
char grade;
if (score >= 90) {
grade = 'A';
} else if (score >= 80) {
grade = 'B';
} else if (score >= 70) {
grade = 'C';
} else if (score >= 60) {
grade = 'D';
} else {
grade = 'F';
}
System.out.println("Your grade is: " + grade);
}
}

Output:

Your grade is: B

You can place an if or if-else structure inside another if or else block. This allows for more complex condition checking, but excessive nesting can make code hard to read.

if (outer_condition) {
// Outer condition is true
if (inner_condition) {
// Both outer and inner conditions are true
} else {
// Outer is true, inner is false
}
} else {
// Outer condition is false
}
public class NestedIfExample {
public static void main(String[] args) {
int age = 25;
boolean hasLicense = true;
if (age >= 18) {
System.out.println("Eligible to drive based on age.");
if (hasLicense) {
System.out.println("Authorized to drive.");
} else {
System.out.println("Needs a driving license.");
}
} else {
System.out.println("Not eligible to drive yet.");
}
}
}

Output:

Eligible to drive based on age.
Authorized to drive.

The switch statement allows a variable to be tested for equality against a list of values (cases). It can often be a cleaner alternative to long if-else if-else chains when checking a single variable against multiple constant values.

Traditional switch Statement (Pre-Java 14)

Section titled “Traditional switch Statement (Pre-Java 14)”
switch (expression) {
case value1:
// Statements for value1
break; // Crucial: exits the switch
case value2:
// Statements for value2
break;
// ... more cases
default: // Optional: executes if no case matches
// Default statements
// No break needed here if it's the last block
}
  • The expression must evaluate to a byte, short, char, int, their corresponding wrapper types (Byte, Short, Character, Integer), an enum type (since Java 5), or a String (since Java 7).
  • Each case value must be a constant (literal or final variable) compatible with the expression’s type.
  • Duplicate case values are not allowed.
  • The break statement is essential. If omitted, execution “falls through” to the next case’s statements until a break or the end of the switch is reached. This is a common source of bugs.
  • The default case is optional and executes if none of the case values match the expression. It can appear anywhere, but convention places it last.
  • If default is not the last block, it needs a break to prevent fall-through.
public class TraditionalSwitchExample {
public static void main(String[] args) {
int dayOfWeek = 3; // 1=Sun, 2=Mon, ..., 7=Sat
String dayName;
switch (dayOfWeek) {
case 1:
dayName = "Sunday";
break;
case 2:
dayName = "Monday";
break;
case 3:
dayName = "Tuesday";
break;
case 4:
dayName = "Wednesday";
break;
case 5:
dayName = "Thursday";
break;
case 6:
dayName = "Friday";
break;
case 7:
dayName = "Saturday";
break;
default:
dayName = "Invalid day";
break; // Good practice even if last
}
System.out.println("The day is: " + dayName);
}
}

Output:

The day is: Tuesday
public class SwitchFallThrough {
public static void main(String[] args) {
char grade = 'B';
switch (grade) {
case 'A':
System.out.println("Excellent!");
break;
case 'B': // No break here!
case 'C':
System.out.println("Well done");
break;
case 'D':
System.out.println("You passed");
break;
case 'F':
System.out.println("Better try again");
break;
default:
System.out.println("Invalid grade");
}
// Output: Well done (because execution falls through from 'B' to 'C')
}
}

Enhanced switch (Switch Expressions, Java 14+)

Section titled “Enhanced switch (Switch Expressions, Java 14+)”

Java 14 introduced enhanced switch features, usable both as statements and expressions (that return a value). They offer a more concise syntax, eliminate fall-through by default, and improve code clarity.

// As a statement
switch (expression) {
case value1 -> // Single statement;
case value2 -> {
// Block of statements
}
// ... other cases
default -> // Default statement or block;
}
// As an expression (returning a value)
ResultType result = switch (expression) {
case value1 -> valueToReturn1;
case value2, value3 -> valueToReturn2; // Multiple labels per case
case value4 -> {
// Complex logic in a block
yield calculatedValue; // Use yield to return value from block
}
default -> defaultValue;
}; // Note the semicolon needed for expression
  • Arrow syntax (->): Code to the right of the arrow executes only for that case. No fall-through!
  • Multiple case labels: You can group multiple constants for the same execution block (e.g., case 'B', 'C' -> ...).
  • No break needed: The arrow syntax inherently prevents fall-through.
  • Exhaustiveness (for expressions): When used as an expression, the switch must cover all possible values of the expression (either through case labels or a default branch) to ensure a value is always returned. The compiler enforces this.
  • yield keyword: Used inside a block ({}) on the right side of an arrow (->) to return a value for that case in a switch expression.
public class EnhancedSwitchExample {
public static void main(String[] args) {
int dayOfWeek = 3; // 1=Mon, ..., 7=Sun
String dayType = switch (dayOfWeek) {
case 1, 2, 3, 4, 5 -> "Weekday";
case 6, 7 -> "Weekend";
default -> {
System.out.println("Invalid day number: " + dayOfWeek);
yield "Unknown"; // Return value from block
}
};
System.out.println("Day type: " + dayType);
}
}

Output:

Day type: Weekday
  • Use if-else if-else for complex boolean conditions, range checks (score > 90), or checking multiple different variables.
  • Use switch (especially enhanced switch) when checking a single variable against a set of discrete, constant values (int, String, enum). It can often be more readable in these scenarios.

After understanding how to make decisions, the next chapter explores loop control statements (while, do-while, for), which allow you to execute blocks of code repeatedly.