00:00

Ternary Operator in Java – Explained with Examples

The ternary operator ?: is a compact way to choose between two values based on a condition. It is called "ternary" because it is the only Java operator that takes three operands: a condition, a value for true, and a value for false. It is also known as the conditional operator.

This tutorial explains its syntax, when it is better than if-else, how nested ternaries work, how Java decides the result type, and a NullPointerException trap that catches many developers.

1. Syntax

Ternary operator syntax in Java
Syntax
result = condition ? valueIfTrue : valueIfFalse;
  1. The condition is evaluated; it must be a boolean.
  2. If it is true, the expression after ? is evaluated and becomes the result.
  3. If it is false, the expression after : is evaluated instead.

Only one of the two value expressions is evaluated, never both.

2. Basic Examples

TernaryBasics.java
public class TernaryBasics {
    public static void main(String[] args) {
        int a = 42, b = 17;

        int max = (a > b) ? a : b;                         // pick the larger value
        System.out.println("max = " + max);

        int n = 7;
        System.out.println(n + " is " + (n % 2 == 0 ? "even" : "odd"));

        int stock = 0;
        String label = stock > 0 ? "In stock" : "Sold out";
        System.out.println("label = " + label);

        int items = 1;
        System.out.println(items + " item" + (items == 1 ? "" : "s") + " in your cart");

        // The same logic with if-else takes more lines:
        String status;
        if (stock > 0) {
            status = "In stock";
        } else {
            status = "Sold out";
        }
        System.out.println("status = " + status);
    }
}
Output
max = 42
7 is odd
label = Sold out
1 item in your cart
status = Sold out

The ternary version of the stock label takes one line; the if-else version takes six. Because the ternary operator is an expression, it can be used directly in assignments, method arguments, return statements and string concatenation.

3. Nested Ternary Operators

The false branch can itself be another ternary expression, forming a chain. Formatted one condition per line, a chain can read like a lookup table:

NestedTernary.java
public class NestedTernary {
    static String grade(int marks) {
        return marks >= 85 ? "A"
             : marks >= 70 ? "B"
             : marks >= 55 ? "C"
             : marks >= 40 ? "D"
             : "F";
    }

    public static void main(String[] args) {
        for (int m : new int[] {92, 74, 58, 41, 12}) {
            System.out.println(m + " -> " + grade(m));
        }
    }
}
Output
92 -> A
74 -> B
58 -> C
41 -> D
12 -> F

The ternary operator is right-associative, so a ? b : c ? d : e means a ? b : (c ? d : e). Deeply nested or tangled ternaries quickly become hard to read; use if-else or a switch instead.

4. The Result Type and the Null Trap

Both branches must produce a value of a compatible type, and Java converts them to a common type. This leads to two surprises:

TernaryTypes.java
public class TernaryTypes {
    public static void main(String[] args) {
        // Both branches are converted to a common type
        System.out.println(true ? 1 : 2.0);         // prints 1.0 (int promoted to double)
        Object o = true ? 1 : "one";                // common type is Object
        System.out.println(o);

        // Trap: mixing int and a null Integer unboxes the null
        Integer missing = null;
        try {
            Integer value = false ? 0 : missing;    // type is int, so missing is unboxed
            System.out.println(value);
        } catch (NullPointerException e) {
            System.out.println("NullPointerException from unboxing a null Integer");
        }

        Integer safe = false ? Integer.valueOf(0) : missing;   // both Integer: no unboxing
        System.out.println("safe = " + safe);
    }
}
Output
1.0
1
NullPointerException from unboxing a null Integer
safe = null
  • true ? 1 : 2.0 prints 1.0, because the int is promoted to double to match the other branch.
  • When one branch is a primitive int and the other an Integer, the result type is int. If the Integer is null, unboxing it throws NullPointerException, even though the assignment target is an Integer.
  • Keeping both branches as objects (Integer.valueOf(0)) avoids the unboxing.

5. Ternary vs if-else

Ternary operatorif-else statement
An expression: produces a valueA statement: performs actions
Exactly two choices, each a single expressionAny number of branches and statements
Can be used inside assignments, arguments and returnsCannot be used where a value is expected
Best for short, simple choicesBest for complex logic or side effects

A ternary expression cannot stand alone as a statement: x > 0 ? doA() : doB(); does not compile. Use if-else to choose between actions.

6. Ternary vs Switch Expression

For a choice between more than two values, a modern switch expression is clearer than nested ternaries:

TernaryVsSwitch.java
public class TernaryVsSwitch {
    enum Level { LOW, MEDIUM, HIGH }

    public static void main(String[] args) {
        Level level = Level.MEDIUM;

        // Many choices: a switch expression reads better than nested ternaries
        String colour = switch (level) {
            case LOW -> "green";
            case MEDIUM -> "orange";
            case HIGH -> "red";
        };
        System.out.println("colour = " + colour);

        // Two choices: the ternary operator is perfect
        boolean urgent = level == Level.HIGH;
        System.out.println(urgent ? "Notify now" : "Notify later");
    }
}
Output
colour = orange
Notify later

7. Best Practices

  • Use the ternary operator for simple, side-effect-free choices between two values.
  • Put parentheses around the condition when it contains operators, for readability.
  • Avoid nesting more than one level unless each branch is on its own line and the logic is a simple chain.
  • Keep both branches the same type to avoid unexpected promotion or unboxing.
  • For null defaults, consider Objects.requireNonNullElse(value, fallback) or Optional.orElse().

8. Summary

  • condition ? a : b returns a if the condition is true, otherwise b.
  • It is an expression, so it can be used wherever a value is needed.
  • Only one branch is evaluated; the operator is right-associative.
  • Both branches are converted to a common type, which can promote numbers or unbox a null.
  • Use if-else for actions and switch for many choices.

Related Tutorials