この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:3
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: 論理演算子
SEOタイトル: Java 論理演算子完全ガイド (&&/||/!) - 短絡評価と非短絡の違い

この記事の要点
  • Java の論理演算子は && (AND) / || (OR) / ! (NOT)
  • &&||短絡評価 (short-circuit) → 左辺で結果確定なら右辺を評価しない
  • & / |非短絡。boolean なら論理演算、整数ならビット演算
  • null チェックの定石: if (obj != null && obj.method()) ← 短絡で NullPointerException 回避
  • 三項演算子 cond ? a : b、Java 14+ 式 switch case L1, L2 -> ...

3 つの基本論理演算子

演算子名称真理表短絡
&&論理 AND両方 true で true★ する
||論理 ORどちらか true で true★ する
!論理 NOTtrue ⇔ false 反転-
&ビット AND / 非短絡 AND同上 (boolean のとき)しない
|ビット OR / 非短絡 OR同上 (boolean のとき)しない
^XOR異なる値で true-
boolean a = true;
boolean b = false;

a && b;    // false
a || b;    // true
!a;        // false

// 値が等しいか
int x = 5;
(x > 0) && (x < 10);   // true
(x < 0) || (x > 100);  // false

// XOR (排他的論理和)
true ^ false;   // true
true ^ true;    // false

短絡評価 (Short-Circuit Evaluation)

&& は左辺が false なら右辺を評価しません。|| は左辺が true なら右辺を評価しません。これは性能だけでなくNullPointerException 回避の定石として使います。

// ★ 定石: null チェック + メソッド呼び出し
String s = getString();  // null かもしれない

// ❌ 危険: s が null だと NullPointerException
if (s.length() > 0 && s != null) { ... }

// ✅ 短絡で安全
if (s != null && s.length() > 0) {
    // s != null が false なら s.length() は評価されない
    System.out.println(s);
}

// OR 版
if (s == null || s.isEmpty()) {
    System.out.println("空");
}

// 副作用に注意 (右辺が呼ばれないことがある)
int counter = 0;
boolean f() { counter++; return true; }

if (false && f()) { ... }   // f() は呼ばれない → counter 増えない
if (true  || f()) { ... }   // f() は呼ばれない

非短絡演算子 (& / |)

boolean に対して & / | を使うと必ず両辺を評価します。副作用が必要な特殊ケースのみ:

// ❌ 普通は使わない
if (validateA() & validateB()) {
    // 両方のバリデーション関数を必ず呼ぶ
    // エラーを両方記録したいときなど
}

// 整数では純粋にビット演算
int flags = 0b1010;
int mask  = 0b1100;

flags & mask;    // 0b1000 = 8
flags | mask;    // 0b1110 = 14
flags ^ mask;    // 0b0110 = 6
~flags;          // ビット反転

// シフト
flags << 2;      // 0b101000 = 40
flags >> 1;      // 0b101 = 5
flags >>> 1;     // 符号なし右シフト

三項演算子 (Conditional Operator)

int age = 20;
String label = age >= 18 ? "成人" : "未成年";

// ネスト可能だが可読性が下がる
String grade = score >= 90 ? "A"
             : score >= 80 ? "B"
             : score >= 70 ? "C"
             : "F";

// null 合体 (Java では Objects.requireNonNullElse)
String name = Objects.requireNonNullElse(input, "default");
// または
String name2 = (input != null) ? input : "default";

// Optional (Java 8+)
String s = Optional.ofNullable(input).orElse("default");

Java 14+ 式 switch (Switch Expression)

// 従来 switch (文)
String label;
switch (day) {
    case MONDAY:
    case TUESDAY:
        label = "平日"; break;
    case SATURDAY:
    case SUNDAY:
        label = "週末"; break;
    default:
        label = "?";
}

// Java 14+ 式 switch (値を返す、break 不要)
String label2 = switch (day) {
    case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "平日";
    case SATURDAY, SUNDAY -> "週末";
};

// 複雑な処理は yield
int v = switch (op) {
    case "add" -> a + b;
    case "sub" -> a - b;
    default -> {
        log("unknown op: " + op);
        yield 0;
    }
};

演算子優先順位

論理演算子の優先順位 (高 → 低):

  1. ! (NOT) - 単項
  2. *, /, %
  3. +, -
  4. <, >, <=, >=, instanceof
  5. ==, !=
  6. & (ビット/論理 AND)
  7. ^ (XOR)
  8. | (ビット/論理 OR)
  9. &&
  10. ||
  11. ? : (三項)
  12. =, +=, ...
// && は || より優先順位が高い
a || b && c    // a || (b && c) と同じ
(a || b) && c  // 明示

// 比較 → 論理 の順
x > 0 && x < 10   // (x > 0) && (x < 10)

// ! の落とし穴
!a == b      // (!a) == b
!(a == b)    // 等値の否定

JavaScript との違い

項目JavaJavaScript
&& の戻り値必ず boolean最後に評価した値 (truthy/falsy)
|| の戻り値必ず boolean最後に評価した値
truthy/falsy無し (boolean のみ)あり (0, "", null, undefined は falsy)
null 合体Objects.requireNonNullElse??
// JavaScript では && / || は値を返す
"abc" || "default"   // "abc"
null || "default"    // "default"
0 && "x"             // 0
1 && "x"             // "x"

// JS のデフォルト値イディオム (古い)
const name = input || "default";  // input が "" だと "default" に!

// JS の正しい null 合体 (ES2020+)
const name = input ?? "default";  // null/undefined のときだけ

FAQ

Q: &&& の使い分けは?
A: 99% は &&& は両辺の副作用が必要な特殊ケース or 整数ビット演算のとき。

Q: !flag == true と書いて警告された
A: !(flag == true) ではなく (!flag) == true と解釈されます。意図と違う可能性。素直に !flagflag != true

Q: 条件が複雑すぎて読みにくい
A: 意味のある変数に分解します。boolean isAdult = age >= 18; のように。