一、高度な分岐の使用法:ネストされた分岐(if-else/switch のネスト)
ネストされた分岐は「分岐の中に分岐がある」もので、多段階の条件判断に適しています(例:ユーザー種別を判定し、その後ユーザーのレベルを判定)。企業開発では頻繁に使用されますが、読みやすさのためにネストの深さは3層までに制限することが推奨されます。
1. if-else ネストの例(ユーザ権限の判定)
public class NestedIfDemo {
public static void main(String[] args) {
String role = "admin"; // ロール: admin/normal
int level = 2; // 管理者レベル: 1-3
if (role.equals("admin")) {
if (level >= 2) {
System.out.println("上級管理者、すべての機能にアクセス可");
} else {
System.out.println("一般管理者、基本機能のみアクセス可");
}
} else if (role.equals("normal")) {
System.out.println("一般ユーザー、バックエンドへのアクセス不可");
} else {
System.out.println("未知のロール、権限チェック失敗");
}
}
}
**企業規範**: ネストされた分岐は最大3層まで。それ以上の場合、メソッドに分割する(例:`checkAdminLevel(int level)`)。
2. switch ネストの例(注文ステータス + 支払い方法の判定)
public class NestedSwitchDemo {
public static void main(String[] args) {
String orderStatus = "PAID"; // 注文ステータス: UNPAID/PAID/CANCEL
String payType = "WECHAT"; // 支払い方法: ALIPAY/WECHAT
switch (orderStatus) {
case "PAID":
switch (payType) {
case "ALIPAY":
System.out.println("支付宝支付,已入账");
break;
case "WECHAT":
System.out.println("微信支付,已入账");
break;
default:
System.out.println("未知支付方式,需核对");
}
break;
case "UNPAID":
System.out.println("订单未支付,提醒用户付款");
break;
default:
System.out.println("订单状态异常");
}
}
}
二、JDK 14+ の新機能:switch 式(企業での主流の新しい使用法)
従来の switch 文は「文」(戻り値なし)でしたが、JDK 14 から switch 式(戻り値あり)がサポートされました。より簡潔で、break を忘れにくいです。
1. コア文法(従来の switch との比較)
| 従来の switch(文) | switch 式(JDK14+) |
|---|---|
| break 必須、なければ貫通 | 自動終了、break 不要 |
| 戻り値なし、コード実行のみ | 戻り値あり、変数に直接代入可能 |
| 文法が複雑 | 矢印文法 `->` サポート、簡潔 |
2. 実践例:月から季節を取得(switch 式)
public class SwitchExpressionDemo {
public static void main(String[] args) {
int month = 4;
// 従来の switch(break 必須)
String season1;
switch (month) {
case 1: case 2: case 12:
season1 = "冬季";
break;
case 3: case 4: case 5:
season1 = "春季";
break;
default:
season1 = "未知月份";
}
// switch 式(JDK14+、簡潔、break 不要)
String season2 = switch (month) {
case 1, 2, 12 -> "冬季";
case 3, 4, 5 -> "春季";
case 6, 7, 8 -> "夏季";
case 9, 10, 11 -> "秋季";
default -> "未知月份";
};
System.out.println("传统switch:" + season1); // 春季
System.out.println("switch表达式:" + season2); // 春季
}
}
3. 高度な使用法:yield キーワード(式内の複雑な論理)
public class SwitchYieldDemo {
public static void main(String[] args) {
int score = 88;
String grade = switch (score / 10) {
case 10, 9 -> "A";
case 8 -> {
System.out.println("成绩良好,等级B");
yield "B";
}
case 7, 6 -> "C";
default -> "D";
};
System.out.println("成绩等级:" + grade); // B
}
}
三、企業レベルの分岐の最適化技術(初心者必見)
1. 複数条件の if-else → Map に置き換え(列挙 / 定数マッピング)
import java.util.HashMap;
import java.util.Map;
public class IfToMapDemo {
private static final Map STATUS_MAP = new HashMap<>();
static {
STATUS_MAP.put(200, "成功");
STATUS_MAP.put(400, "参数错误");
STATUS_MAP.put(500, "服务器异常");
}
public static void main(String[] args) {
int code = 200;
String msg1;
if (code == 200) {
msg1 = "成功";
} else if (code == 400) {
msg1 = "参数错误";
} else if (code == 500) {
msg1 = "服务器异常";
} else {
msg1 = "未知状态";
}
String msg2 = STATUS_MAP.getOrDefault(code, "未知状态");
System.out.println(msg1); // 成功
System.out.println(msg2); // 成功
}
}
2. 複雑な条件 → メソッドに分割(可読性の向上)
public class ConditionSplitDemo {
public static void main(String[] args) {
int score = 85;
int type = 1; // 1=期末考,2=模拟考
if (score >= 60 && score <= 100 && type == 1) {
System.out.println("期末考及格");
}
if (isFinalExamPass(score, type)) {
System.out.println("期末考及格");
}
}
private static boolean isFinalExamPass(int score, int type) {
return score >= 60 && score <= 100 && type == 1;
}
}
3. 早期 return(else 層の削減)
public class EarlyReturnDemo {
public static String checkUser(String username, String password) {
if (username == null || username.isEmpty()) {
return "用户名不能为空";
}
if (password == null || password.length() < 6) {
return "密码长度不能小于6位";
}
return "用户校验通过";
}
public static void main(String[] args) {
System.out.println(checkUser("zhangsan", "123456")); // 用户校验通过
System.out.println(checkUser(null, "123456")); // 用户名不能为空
}
}
四、初心者のよくある落とし穴(企業面接 / 開発でよく問われる)
1. switch の「貫通問題」(従来の switch での必須注意点)
public class SwitchPenetrationDemo {
public static void main(String[] args) {
int num = 1;
switch (num) {
case 1:
System.out.println("执行case1"); // 会执行
case 2:
System.out.println("执行case2"); // 漏break,也会执行(穿透)
default:
System.out.println("执行default");
}
}
}
// 输出:
// 执行case1
// 执行case2
// 执行default
**避坑**:従来の switch では各 case の末尾に break を追加する必要がある;JDK14+ では switch 式を使用して自動的に回避。
2. if 条件の「定数を左側に置く」(空ポインタ例外の回避)
public class IfNpeDemo {
public static void main(String[] args) {
String name = null;
if (name.equals("zhangsan")) {
System.out.println("匹配");
}
if ("zhangsan".equals(name)) {
System.out.println("匹配");
}
}
}
3. 浮動小数点数の switch 使用禁止(文法エラー)
public class SwitchFloatError {
public static void main(String[] args) {
double num = 1.0;
if (num == 1.0) {
System.out.println("1.0");
}
}
}
五、分岐構造の完全な使用ルール(まとめ)
- 単純な条件判定 → 単一の if/if-else(例えば、2つの選択肢、範囲判定)
- 固定値のマッチ(少量)→ 従来の switch(JDK14-)/switch 式(JDK14+)
- 固定値のマッチ(大量)→ 多重の if-else/switch に代わる Map マッピング
- 多段階の条件 → ネストされた分岐(最大3層)、それ以上はメソッドに分割
- 複雑な条件 → 読みやすいようにメソッドに分割し、早期 return で else 層を削減
- 避けるべき落とし穴:switch には break を追加、if では定数を左側に置く、浮動小数点数は switch で使わない、ネストは3層以内