HOWTO · Java

Use AND and OR Operators in Java

Use Java's && and || operators to combine boolean conditions, understand short-circuit evaluation, and avoid confusing them with & and |.

On this page

Use && when every condition must be true and || when at least one condition may be true. Both are Java’s short-circuit operators: Java evaluates the left side first and evaluates the right side only when it still needs that value. That makes a guard such as text != null && !text.isEmpty() safe: isEmpty() is not called when text is null.

Use ! to reverse one boolean condition. Java conditions require boolean or Boolean values; unlike JavaScript, an integer or a nonempty string is not silently treated as true. The Java Language Specification defines && as conditional AND and || as conditional OR. Its rules for && and || also explain exactly when the right-hand expression is skipped.

Choose &&, ||, or !

&& produces true only when both operands are true. || produces true when either operand is true. ! reverses a boolean value. Use them to make the business rule visible instead of nesting unrelated if statements.

The following complete program checks a membership rule and a numeric range. It was compiled and run in the Polyglot image with OpenJDK 11.0.32; the operators are also specified in the current Java SE 26 language specification.

public class LogicalOperators {
    public static void main(String[] args) {
        boolean hasTicket = true;
        boolean isMember = false;

        System.out.println("ticket && member: " + (hasTicket && isMember));
        System.out.println("ticket || member: " + (hasTicket || isMember));
        System.out.println("!member: " + !isMember);

        int age = 20;
        boolean canEnter = age >= 18 && age <= 65;
        System.out.println("can enter: " + canEnter);
    }
}

Output:

ticket && member: false
ticket || member: true
!member: true
can enter: true

The range test uses && because an age must satisfy both limits. A permission rule such as isAdmin || hasTemporaryPass uses || because either condition is sufficient. Parenthesize a mixed expression when the grouping is not obvious to the next reader, even if you know the operator precedence.

Put the null check first

Short-circuiting is especially useful when the right side would dereference a value that might be null. Place the inexpensive safety condition on the left:

public class ShortCircuitBoundary {
    public static void main(String[] args) {
        String text = null;

        boolean safe = text != null && !text.isEmpty();
        System.out.println("&& with null: " + safe);

        try {
            boolean unsafe = text != null & !text.isEmpty();
            System.out.println("& with null: " + unsafe);
        } catch (NullPointerException exception) {
            System.out.println("& with null: NullPointerException");
        }
    }
}

Output:

&& with null: false
& with null: NullPointerException

With &&, the false result of text != null decides the whole expression, so Java does not call text.isEmpty(). This is a boundary case, not merely a performance trick: it prevents that dereference. Scanner.nextLine() is not a nullable-string source—it returns a line or fails when no line is available—but nullable method results, optional configuration values, and fields often need this pattern.

Know what short-circuiting does not protect

Short-circuiting skips only the right-hand expression when the left-hand value already decides the result. It does not make every expression null-safe. For example, a Boolean enabled = null must be checked with enabled != null && enabled before Java can unbox it. Writing enabled && otherCondition attempts to unbox enabled first and can throw NullPointerException.

Likewise, do not place a required operation on a side that may be skipped. isConfigured || createConfiguration() does not call createConfiguration() when the setting is already configured. That is useful for a fallback check, but it is the wrong form when creation must always happen. Keep predicates free of mutations where possible, and call required work in a separate statement.

Do not replace && with &

& and | can also accept boolean operands, but they always evaluate both operands. They additionally have their familiar bitwise meaning for integral operands. Their boolean result may match && or ||, yet their evaluation behaviour does not. Choose && and || for ordinary guards and conditions; use a single-character operator only when evaluating both sides is intentional and safe.

Avoid relying on side effects such as index++ or a method that changes state inside either operand. Short-circuiting can make that side effect run in one path and not another. Extract a named boolean or method when a condition becomes hard to read, and use parentheses to document the intended grouping. For the formal distinction between boolean &/| and the conditional operators, see JLS §§15.22.2–15.24.