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

タイトル: 制御構文
SEOタイトル: Java 制御構文完全ガイド (if/switch/for/while)

この記事の要点
  • 分岐: if/else / switch (古い文 + Java 14+ 新しい式) / 三項演算子
  • 繰り返し: for / 拡張 for / while / do-while
  • 脱出: break / continue / return / ラベル付き break
  • モダン: switch 式 (Java 14+)、Pattern Matching (Java 17+/21)、enhanced switch、try-with-resources
  • do-while最低 1 回は実行while は条件 false なら 0 回

if / else / else if

int score = 75;

if (score >= 90) {
    System.out.println("A");
} else if (score >= 70) {
    System.out.println("B");       // ← ここに入る
} else if (score >= 50) {
    System.out.println("C");
} else {
    System.out.println("F");
}

// 単一行は { } 省略可能だがバグの温床なので推奨しない
if (x > 0) System.out.println("positive");

三項演算子

// 条件 ? 真の値 : 偽の値
int age = 20;
String label = (age >= 20) ? "大人" : "未成年";

// ネストは可能だが読みにくい
String grade = score >= 90 ? "A"
             : score >= 70 ? "B"
             : score >= 50 ? "C" : "F";

// ★ null チェック
String name = (user != null) ? user.getName() : "(unknown)";
// Java 8+ は Optional 推奨
String name2 = Optional.ofNullable(user).map(User::getName).orElse("(unknown)");

switch (古い文と新しい式)

古い switch 文 (Java 13 以前)

int day = 3;
String name;
switch (day) {
    case 1:
        name = "月";
        break;                    // ★ break 忘れると次に流れる (fall-through)
    case 2:
        name = "火";
        break;
    case 3:
    case 4:
        name = "水or木";          // フォールスルーで複数 case
        break;
    default:
        name = "?";
        break;
}

新しい switch 式 (Java 14+)

// 矢印構文 -> はフォールスルーしない (break 不要)
String name = switch (day) {
    case 1 -> "月";
    case 2 -> "火";
    case 3, 4 -> "水or木";          // ★ カンマで複数 case まとめ
    default -> "?";
};

// 複数行は yield
String label = switch (day) {
    case 1, 2, 3, 4, 5 -> "平日";
    case 6, 7 -> {
        log.info("休日です");
        yield "休日";              // ★ switch 式の戻り値
    }
    default -> throw new IllegalArgumentException();
};

Pattern Matching (Java 21+)

// 型と値による分岐
sealed interface Shape permits Circle, Square {}
record Circle(double r) implements Shape {}
record Square(double s) implements Shape {}

double area = switch (shape) {
    case Circle c -> Math.PI * c.r() * c.r();
    case Square sq -> sq.s() * sq.s();
};

// ガード節 (when)
String size = switch (n) {
    case Integer i when i < 0 -> "negative";
    case Integer i when i == 0 -> "zero";
    case Integer i -> "positive";
};

for 文

// 初期化; 条件; 更新
for (int i = 0; i < 10; i++) {
    System.out.println(i);
}

// 2 つ並列
for (int i = 0, j = 10; i < j; i++, j--) {
    System.out.println(i + "," + j);
}

// 無限ループ
for (;;) {
    if (done) break;
}

// 拡張 for (for-each)
for (String name : names) {
    System.out.println(name);
}

while と do-while の使い分け

構文条件チェック最低実行回数
whileループ前0 回
do-whileループ後1 回
// while: 条件が最初から false なら 1 度も実行されない
int i = 10;
while (i < 5) {
    System.out.println(i);    // ★ 表示されない
}

// do-while: 必ず 1 回は実行
int j = 10;
do {
    System.out.println(j);    // ★ 10 を 1 回表示
} while (j < 5);

// 典型例: ユーザー入力ループ
String input;
do {
    System.out.print("Enter (q to quit): ");
    input = scanner.nextLine();
    process(input);
} while (!input.equals("q"));

break / continue / ラベル付き

for (int i = 0; i < 10; i++) {
    if (i == 3) continue;     // この回をスキップ → 0,1,2,4,5,6,7,8,9
    if (i == 7) break;        // ループ脱出   → 0,1,2,4,5,6
    System.out.println(i);
}

// ラベル付き break で多重ループ一気に脱出
outer:
for (int[] row : matrix) {
    for (int n : row) {
        if (n == -1) break outer;     // ★ 外側ループも脱出
    }
}

// ラベル付き continue で外側ループの次イテレーション
outer:
for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
        if (skip[i][j]) continue outer;   // 外側ループの次へ
    }
}

try-with-resources (Java 7+)

AutoCloseable を実装したリソースを自動で閉じます。finallyclose() を呼ぶ昔の書き方より安全。

// 自動クローズ
try (
    FileReader fr = new FileReader("a.txt");
    BufferedReader br = new BufferedReader(fr)
) {
    String line;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
}   // ★ ここで br → fr の順に自動 close

// 例外も自動でログ
try (Connection conn = DriverManager.getConnection(url);
     PreparedStatement ps = conn.prepareStatement(sql);
     ResultSet rs = ps.executeQuery()) {
    while (rs.next()) { ... }
}

null チェックの定番

// クラシック
if (user != null && user.getName() != null) {
    System.out.println(user.getName().length());
}

// Java 8+ Optional
Optional.ofNullable(user)
    .map(User::getName)
    .ifPresent(n -> System.out.println(n.length()));

// Objects ユーティリティ
String name = Objects.requireNonNullElse(user.getName(), "(unknown)");

// Objects.requireNonNull (ガード節)
public void setUser(User u) {
    this.user = Objects.requireNonNull(u, "user must not be null");
}

例外による制御

try {
    int n = Integer.parseInt(input);
} catch (NumberFormatException e) {
    System.err.println("not a number: " + input);
} catch (Exception e) {
    System.err.println("other: " + e);
} finally {
    System.out.println("always");
}

// マルチキャッチ (Java 7+)
try {
    ...
} catch (IOException | SQLException e) {
    log.error(e);
}

FAQ

Q: switch と if/else どちらを使う?
A: 比較対象が同じ変数で 3 つ以上の値で分岐するなら switch。範囲比較 (x > 0) は if。Java 14+ の switch 式は記述量が少なく推奨。

Q: 古い break 付き switch はもう不要?
A: Java 14+ は新しい矢印構文 (->) を強く推奨。fall-through バグの温床を排除できます。

Q: while(true) と for(;;) はどちらが好まれる?
A: 機能的に同じ。可読性は while (true)、コンパイラ警告を避けたいなら for (;;) という流派もある。