タイトル: 条件分岐 (if文)
SEOタイトル: Java 条件分岐完全ガイド — if/switch/三項/パターンマッチ
| この記事の要点 |
|
if / else if / else
int score = 75;
if (score >= 90) {
System.out.println("A");
} else if (score >= 80) {
System.out.println("B");
} else if (score >= 70) {
System.out.println("C");
} else {
System.out.println("F");
}
// 1 行なら波括弧省略可 (ただし非推奨 → バグの温床)
if (x > 0) System.out.println("正"); // ★ 後で行を追加するとバグる
// ✅ 必ず波括弧を付ける (Google Java Style 推奨)
if (x > 0) {
System.out.println("正");
}
三項演算子
int n = 5;
String sign = n > 0 ? "正" : (n < 0 ? "負" : "ゼロ");
// 変数代入や return と相性が良い
String greeting = isMorning ? "おはよう" : "こんにちは";
return user == null ? "Guest" : user.getName();
// ❌ 複雑になったら if へ戻す
String result = a > 0 ? (b > 0 ? (c > 0 ? "all+" : "ab+") : "a+") : "neg";
// ★ 読めない
switch 文 (旧記法)
String day = "MONDAY";
switch (day) {
case "MONDAY":
case "TUESDAY":
case "WEDNESDAY":
case "THURSDAY":
case "FRIDAY":
System.out.println("平日");
break; // ★ break 忘れに注意 (fall-through)
case "SATURDAY":
case "SUNDAY":
System.out.println("週末");
break;
default:
System.out.println("不明");
}
switch 式 (Java 14+) ★ 推奨
// アロー記法 + 値を返せる + break 不要
String type = switch (day) {
case "SATURDAY", "SUNDAY" -> "週末";
case "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY" -> "平日";
default -> "不明";
};
// ブロック + yield
int hours = switch (day) {
case "FRIDAY" -> {
System.out.println("花金");
yield 6;
}
case "SATURDAY", "SUNDAY" -> 0;
default -> 8;
};
// switch 式は ★ 全パターン網羅必須 (網羅していないとコンパイルエラー)
pattern matching switch (Java 21+) ★ 最新
Object o = "Hello";
String describe = switch (o) {
case Integer i when i > 0 -> "正の整数: " + i;
case Integer i -> "0以下の整数: " + i;
case String s -> "文字列: " + s;
case int[] arr -> "int 配列 長さ " + arr.length;
case null -> "null!";
default -> "その他";
};
// sealed クラスとの組み合わせ (網羅性チェック付き)
sealed interface Shape permits Circle, Square, Rectangle {}
record Circle(double r) implements Shape {}
record Square(double a) implements Shape {}
record Rectangle(double w, double h) implements Shape {}
double area(Shape s) {
return switch (s) {
case Circle c -> Math.PI * c.r() * c.r();
case Square sq -> sq.a() * sq.a();
case Rectangle r -> r.w() * r.h();
// default 不要 (sealed なので網羅)
};
}
null チェックの典型パターン
String s = getValue();
// 基本
if (s == null) {
return "default";
}
// 短絡で安全に呼び出し
if (s != null && s.length() > 0) { ... }
// Optional を使う (Java 8+)
Optional<String> opt = Optional.ofNullable(s);
opt.ifPresent(v -> System.out.println(v));
String result = opt.orElse("default");
// Yoda 記法 (定数を左に置いてミスを防ぐ)
if (null == s) { ... } // s が null かどうか
// if (s = null) ←代入と間違えても s 側にしておけばコンパイルエラーで気付ける
早期 return (Early Return) でネストを浅く
// ❌ ネストが深い
public String process(User u) {
if (u != null) {
if (u.isActive()) {
if (u.getEmail() != null) {
return u.getEmail().toLowerCase();
} else {
return "no email";
}
} else {
return "inactive";
}
} else {
return "null";
}
}
// ✅ ガード節で早期 return
public String process2(User u) {
if (u == null) return "null";
if (!u.isActive()) return "inactive";
if (u.getEmail() == null) return "no email";
return u.getEmail().toLowerCase();
}
複雑な条件のリファクタリング
// ❌ 条件が呪文
if (user != null && user.getAge() >= 20 && user.getCountry().equals("JP")
&& (user.getStatus() == Status.ACTIVE || user.getStatus() == Status.VIP)) {
sendCampaign(user);
}
// ✅ メソッド化 + 名前で意図を表現
if (isTargetForJapanAdultCampaign(user)) {
sendCampaign(user);
}
private boolean isTargetForJapanAdultCampaign(User u) {
if (u == null) return false;
if (u.getAge() < 20) return false;
if (!"JP".equals(u.getCountry())) return false; // ★ "JP".equals でも NPE 防止
return u.getStatus() == Status.ACTIVE || u.getStatus() == Status.VIP;
}
== と equals() の使い分け
| 比較対象 | 使う | 例 |
|---|---|---|
| 基本型 (int / long / double) | == | x == 0 |
| String | .equals() | s.equals("abc") |
| String と null チェック | Yoda .equals() | "abc".equals(s) |
| 参照同一性 | == | obj == this |
| enum | == | status == Status.ACTIVE |
| Integer / Long | .equals() | boxing 値はキャッシュ範囲外で == NG |
FAQ
Q: switch と if、どちらを使うべき?
A: 等価判定の多分岐は switch (式) が読みやすい。範囲判定 (x > 0 等) は if。
Q: if (x = 5) のバグを防ぐには?
A: Java では条件式は boolean のみなので if (x = 5) はコンパイルエラーで気付けます (boolean 同士なら可)。
Q: else if の連続は何個まで OK?
A: 目安は 3〜4 個。それ以上は switch / Strategy パターン / Map による分岐表に置き換える。