package Dec2016;
public class Ques1206 {
public static void main(String[] args) {
doSex(null);
}
public static void doSex(Sex sex) {
switch (sex) {
case Boy:
System.out.println("男的");
break;
case Girl:
System.out.println("女的");
break;
default:
System.out.println("出錯");
break;
}
}
}
enum Sex {
Boy("男"), Girl("女");
private String sex;
Sex(String sex) { this.sex = sex; }
}
答案:運行時拋出 NullPointerException,無法正常輸出。
main 呼叫 doSex(null),參數 sex 為 nullswitch (sex) 表達式求值switch 表達式為引用類型時,若值為 null → 拋出 NullPointerExceptionswitch 行拋出,不進入任何 case/default 分支| 場景 | 編譯期 | 運行期 |
|---|---|---|
| switch 表達式為 null | ✅ 編譯通過 | ❌ 拋出 NPE |
| case 常量非枚舉成員 | ❌ 編譯錯誤 | - |
| 缺少 default 分支 | ✅ 編譯通過 (枚舉 switch 不強制) | 匹配不到 → 無動作 |
| 枚舉新增成員未更新 switch | ✅ 編譯通過 | ⚠️ 走 default 或無匹配 |
public static void doSex(Sex sex) {
if (sex == null) {
System.out.println("出錯:性別不能為空");
return;
}
switch (sex) {
case Boy: System.out.println("男的"); break;
case Girl: System.out.println("女的"); break;
default: System.out.println("出錯:未知性別"); // 防禦性編程
}
}
public static void doSex(Sex sex) {
Objects.requireNonNull(sex, "性別不能為空");
// switch 邏輯...
}
// Java 12+ switch 表達式仍會對 null 拋出 NPE,但語法更簡潔
public static String doSex(Sex sex) {
return switch (sex) {
case Boy -> "男的";
case Girl -> "女的";
default -> throw new IllegalArgumentException("未知性別: " + sex);
};
}
nullsealed interface + permits 編譯期窮盡性檢查ordinal() 易破壞// 反編譯後類似結構
int index = sex == null ? -1 : sex.ordinal(); // null 檢查在這裡
switch (index) {
case 0: // Boy
case 1: // Girl
default:
}
可見 null 檢查發生在 ordinal() 呼叫前,直接導致 NPE。
if (sex == Sex.Boy) 配合 null 如何表現? → 安全,null == Enum 為 falseEnumSet / EnumMap 如何處理 null? → EnumMap key 為 null 拋 NPE,EnumSet 不允許 null 元素