HOWTO · Java

Java で AND と OR 演算子を使用する

Java の && と || で boolean 条件を組み合わせ、短絡評価と &・| の違いを理解します。

このページの内容

&& はすべての条件が真である必要があるとき、|| はどれか一つでよいときに使います。どちらも短絡評価を行うため、右辺が結果を変えられる場合だけ評価されます。したがって text != null && !text.isEmpty() では、text が null のとき isEmpty() は呼ばれません。

! は boolean 条件を反転します。Java が受け取るのは boolean または Boolean であり、数値や文字列を真偽値に暗黙変換しません。Java Language Specification が規則を定義しています。

&&、||、! を選ぶ

&& は両方が真の場合だけ真、|| は一方が真なら真です。次のプログラムは Polyglot の OpenJDK 11.0.32 でコンパイルして実行しました。

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);
    }
}
ticket && member: false
ticket || member: true
!member: true
can enter: true

最初に null を確認する

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");
        }
    }
}
&& with null: false
& with null: NullPointerException

&& では左側の false が結果を決めるため、右側を参照しません。& は両側を評価するので、ここでは表示した例外になります。Scanner.nextLine() は null を返しません。このガードは null になり得る戻り値、設定、フィールドに使います。

短絡評価で保護されないこと

短絡評価が省略するのは、左辺だけで結果が決まる場合の右辺だけです。Boolean enabled = null では enabled != null && enabled と確認します。enabled && otherCondition はアンボックス時に NullPointerException になることがあります。必ず必要な処理をスキップされ得る側に置かないでください。

&& を & に置き換えない

& と | は boolean に使えますが常に両側を評価し、整数ではビット演算でもあります。通常のガードには && と || を使ってください。短絡評価でスキップされ得る index++ のような副作用を条件に入れないことも重要です。