Java:条件分岐
1学習の目的
- if・else if・else で複数の条件を扱えるようになる。論理演算子を組み合わせ、複雑な条件も表現できるようになる。
- switch の使い方とbreak忘れの危険性を理解する。Java 14以降の新しい書き方も身につける。
2基礎解説
| 演算子 | 意味 | 例 |
|---|---|---|
| && | かつ(AND) | age >= 20 && member |
| || | または(OR) | a == 1 || a == 2 |
| ! | でない(NOT) | !member |
| == | 等しい(数値のみ) | 文字列は equals |
- 条件は上から順に判定され、最初に当てはまったものだけが実行される。else if を並べたとき、2つ目以降は「前の条件に当てはまらなかった場合」という前提が付く。
- ⚠ switch で break を忘れると、次のcaseも続けて実行される(フォールスルー)。case 1 で止まらず case 2 case 3 まで流れてしまう——気づきにくい不具合の原因。
- Java 14以降は -> を使った switch式が使える。break が不要になり、値を返せるので安全で簡潔。新しく書くならこちらを推奨。
- && は左が false なら右を評価しない(短絡評価)。str != null && str.length() > 0 と書けば、nullのときエラーにならない——順序が重要。
- 文字列の比較は equals(JV03)。if (name == "abc") は危険で、if (name.equals("abc")) と書く。
現場使用例:会員ランクによる割引、在庫状況の判定、入力値の検証、権限チェック。
// if - else if - else
int score = 75;
if (score >= 80) {
System.out.println("優");
} else if (score >= 60) {
System.out.println("良"); // ← ここが実行される
} else {
System.out.println("可");
}
// 論理演算子
if (age >= 20 && isMember) { … } // 両方満たす
if (a == 1 || a == 2) { … } // どちらか
if (!isMember) { … } // ではない
// ⚠ 短絡評価(順序が重要)
if (str != null && str.length() > 0) { … }
// str が null なら右は評価されない → 安全
// 逆順に書くと null のときエラーになる
// switch(従来型・break が必要)
switch (rank) {
case "A":
System.out.println("最上位");
break; // ← 忘れると次に流れる
case "B":
System.out.println("中位");
break;
default:
System.out.println("その他");
}
// ⭐ switch式(Java 14以降・break不要)
String name = switch (n) {
case 1 -> "月";
case 2 -> "火";
case 3 -> "水";
default -> "不明";
};
// 三項演算子(単純な二択に)
String label = (stock == 0) ? "品切れ" : "在庫あり";
3基本ドリル(10問)
出力 == 良
if / else if / else を使う。上から順に判定される。
public class Main {
public static void main(String[] args) {
int score = 75;
if (score >= 80) {
System.out.println("優");
} else if (score >= 60) {
System.out.println("良");
} else {
System.out.println("可");
}
}
}条件は上から順に判定される。75は80以上ではないので次へ進み、60以上に当てはまって「良」が出力される。
A. エラーになる B. 次のcaseも続けて実行される C. 何も起きない D. 最初のcaseだけ実行される 選択★☆☆無料
解答 == B
フォールスルーと呼ばれる挙動。
B
break が無いと下のcaseへ流れ続ける。エラーにならないため気づきにくく、原因究明に時間がかかる不具合になる。
出力 == true
&& で2つの条件をつなぐ。
public class Main {
public static void main(String[] args) {
int age = 25;
boolean isMember = true;
System.out.println(age >= 20 && isMember);
}
}&& は両方が true のときだけ true。片方でも false なら全体が false になる。
public class Main {
public static void main(String[] args) {
int age = 25;
boolean member = true;
if (age >= 20 ____ member) {
System.out.println("対象です");
}
}
}出力 == 対象です
AND を表す記号。アンパサンド2つ。
&&
&& は2つ重ねる。1つだけの & でも動くが、短絡評価が働かないため通常は使わない。
A. 同じ結果 B. エラーになる C. false になる D. true になる 選択★☆☆無料
解答 == B
null に対して length() を呼ぶとどうなるか。
B
NullPointerException で落ちる。&& は左が false なら右を見ないので、null チェックを必ず左に書く。
出力 == 中位
case ごとに break を書く。default も忘れずに。
public class Main {
public static void main(String[] args) {
String rank = "B";
switch (rank) {
case "A":
System.out.println("最上位");
break;
case "B":
System.out.println("中位");
break;
default:
System.out.println("その他");
}
}
}switch は文字列にも使える(Java 7以降)。ただし比較は内部で equals が使われるので、null を渡すとエラーになる点に注意。
public class Main {
public static void main(String[] args) {
int n = 3;
String day = switch (n) {
case 1 ____ "月";
case 2 ____ "火";
case 3 ____ "水";
default ____ "不明";
};
System.out.println(day);
}
}出力 == 水
矢印を表す2文字(マイナスと大なり)。
->
switch式なら break が不要。値を返せるので変数に代入でき、フォールスルーの事故も起きない。
A. if (name == "abc") B. if (name.equals("abc")) C. if (name === "abc") D. if (name.same("abc")) 選択★★☆広告解放
解答 == B
JV03で学んだ文字列比較の原則。
B
文字列の比較は必ず equals。== は「同じ物体か」の判定なので、中身が同じでも false になることがある。
出力 == 123
print(改行なし)で1・2・3を出力する。break を書かない。
public class Main {
public static void main(String[] args) {
int x = 1;
switch (x) {
case 1:
System.out.print("1");
case 2:
System.out.print("2");
case 3:
System.out.print("3");
}
System.out.println();
}
}1だけのはずが123になった。break が無いと下へ流れ続けるので、意図しない処理まで実行されてしまう。
出力 == 品切れ
条件 ? A : (条件2 ? B : C) の形で書ける。
public class Main {
public static void main(String[] args) {
int stock = 0;
String label = (stock == 0) ? "品切れ"
: (stock < 10) ? "残りわずか"
: "在庫あり";
System.out.println(label);
}
}三項演算子は繋げられるが、3段以上は読みにくくなる。複雑になったら if 文に書き直すほうがよい。
4実践シナリオ(5問)
出力 == 割引額:1500円
if / else if で分岐し、equals で文字列を比較する。
public class Main {
public static void main(String[] args) {
String rank = "gold";
int price = 10000;
double rate;
if (rank.equals("gold")) {
rate = 0.15;
} else if (rank.equals("silver")) {
rate = 0.10;
} else {
rate = 0;
}
long discount = Math.round(price * rate);
System.out.println("割引額:" + discount + "円");
}
}equals で比較するのが要点。== を使うと、データベースから読んだ文字列で動かなくなる恐れがある。
出力 == 水
switch (n) { case 1 -> "月"; ... } の形。最後にセミコロンが必要。
public class Main {
public static void main(String[] args) {
int n = 3;
String day = switch (n) {
case 1 -> "月";
case 2 -> "火";
case 3 -> "水";
case 4 -> "木";
case 5 -> "金";
case 6 -> "土";
case 7 -> "日";
default -> "不明";
};
System.out.println(day);
}
}switch式は値を返すので変数に代入できる。従来型より短く、break忘れの心配もない——新しく書くならこちら。
出力 == 未入力です
str != null && !str.isEmpty() の順で書く。順序が重要。
public class Main {
public static void main(String[] args) {
String input = null;
if (input != null && !input.isEmpty()) {
System.out.println("入力あり:" + input);
} else {
System.out.println("未入力です");
}
}
}null チェックを左に書くのが鉄則。逆順にすると null に対して isEmpty() を呼ぶことになり、NullPointerException で落ちる。
出力 == 送料:600円
会員かどうかを先に判定し、非会員の場合だけ金額で分岐する。
public class Main {
public static void main(String[] args) {
int amount = 4800;
boolean isMember = false;
int shipping;
if (isMember) {
shipping = 0;
} else if (amount >= 5000) {
shipping = 0;
} else {
shipping = 600;
}
System.out.println("送料:" + shipping + "円");
}
}条件を段階的に絞り込むのが読みやすい書き方。isMember || amount >= 5000 と1行にもできるが、条件が増えたとき分けたほうが管理しやすい。
出力 == 特典対象です
&& を2つ使って3つの条件をつなぐ。
public class Main {
public static void main(String[] args) {
int age = 25;
boolean isMember = true;
int amount = 3000;
if (age >= 20 && isMember && amount >= 2000) {
System.out.println("特典対象です");
} else {
System.out.println("対象外です");
}
}
}&& はいくつでもつなげられる。ただし条件が4つ5つと増えたら、意味のまとまりごとに変数に分けると読みやすくなる。
5仕上げ課題
データ
・String rank = "gold";
・int price = 8500; int qty = 3;
・int stock = 5;
処理
① 在庫チェック:数量が在庫を超えていたら「在庫不足です(残り5個)」と出力して終了
② 小計 = 単価 × 数量
③ 割引率を switch式 で決定(gold:0.15、silver:0.10、bronze:0.05、それ以外:0)
④ 割引額 = 小計 × 割引率(四捨五入)
⑤ 割引後 = 小計 - 割引額
⑥ 送料:割引後が5000円以上なら0、未満なら600
⑦ 合計 = 割引後 + 送料
期待される出力(5行)
小計:25,500円
会員ランク:gold(15%引き)
割引額:-3,825円
送料:0円
合計:21,675円
※ 割引率は switch式で求め、パーセント表示(15%)も同じ値から計算すること 総合★★★広告解放
出力5行が完全一致
在庫チェックは if で早めに判定し、問題なければ処理を続ける。switch式は値を返すので double rate = switch (rank) {...}; と書ける。パーセント表示は (int)(rate * 100) で求める。金額は String.format("%,d", 値) で整形。
public class Main {
public static void main(String[] args) {
String rank = "gold";
int price = 8500;
int qty = 3;
int stock = 5;
if (qty > stock) {
System.out.println("在庫不足です(残り" + stock + "個)");
return;
}
int subtotal = price * qty;
double rate = switch (rank) {
case "gold" -> 0.15;
case "silver" -> 0.10;
case "bronze" -> 0.05;
default -> 0;
};
long discount = Math.round(subtotal * rate);
long afterDiscount = subtotal - discount;
int shipping = (afterDiscount >= 5000) ? 0 : 600;
long total = afterDiscount + shipping;
System.out.println("小計:" + String.format("%,d", subtotal) + "円");
System.out.println("会員ランク:" + rank + "(" + (int) (rate * 100) + "%引き)");
System.out.println("割引額:-" + String.format("%,d", discount) + "円");
System.out.println("送料:" + shipping + "円");
System.out.println("合計:" + String.format("%,d", total) + "円");
}
}この課題では、3種類の分岐を使い分けている。在庫チェックは if、ランク判定は switch式、送料は三項演算子——それぞれ適した場面が違う。
在庫チェックで return; を使っている点に注目してほしい。条件を満たさないなら早めに処理を打ち切る——この書き方を「早期リターン」と呼ぶ。もし else で残り全部を囲んでいたら、インデントが深くなって読みにくくなっていた。異常な場合を先に片付け、正常な処理は最後にまとめて書くのが実務の定石だ。
switch式 の利点も明確だ。値を返せるので double rate = switch (...) と1つの式で書ける。従来型の switch なら、変数を先に宣言して各caseで代入し、break を書き…と冗長になっていた。しかも break を1つ忘れれば、goldなのに silver の割引率が適用される金銭に関わる不具合になる。
Java 14以降で書くなら、switch式を選ばない理由はほぼない。
次章では繰り返しを学ぶ。1件の注文を処理できるようになったので、今度は何百件でも処理できるようにしていく。