Java 12 Switch 表达式详解
Java 12 引入了 Switch 表达式作为预览特性,这是对传统 Switch 语句的重大改进,以下是详细案例:

传统 Switch vs Switch 表达式
传统 Switch 语句(Java 8 及之前)
// 传统写法:容易出现穿透问题,代码冗长
public static String getDayType(int day) {
String type;
switch (day) {
case 1:
case 2:
case 3:
case 4:
case 5:
type = "工作日";
break;
case 6:
case 7:
type = "周末";
break;
default:
type = "无效日期";
break;
}
return type;
}
Java 12 Switch 表达式
// 新写法:简洁、无穿透、有返回值
public static String getDayType(int day) {
return switch (day) {
case 1, 2, 3, 4, 5 -> "工作日";
case 6, 7 -> "周末";
default -> "无效日期";
};
}
箭头语法(Arrow Syntax)
基本用法
public class SwitchExpressionDemo {
public static void main(String[] args) {
// 示例1:季节判断
String season = getSeason(3);
System.out.println("3月是: " + season); // 输出:3月是: 春季
// 示例2:数值计算
int result = calculate(10, 5, '+');
System.out.println("10 + 5 = " + result); // 输出:10 + 5 = 15
}
// 季节判断
static String getSeason(int month) {
return switch (month) {
case 12, 1, 2 -> "冬季";
case 3, 4, 5 -> "春季";
case 6, 7, 8 -> "夏季";
case 9, 10, 11 -> "秋季";
default -> "无效月份";
};
}
// 简单计算器
static int calculate(int a, int b, char operator) {
return switch (operator) {
case '+' -> a + b;
case '-' -> a - b;
case '*' -> a * b;
case '/' -> a / b;
default -> throw new IllegalArgumentException("无效运算符: " + operator);
};
}
}
多值匹配
public class MultiValueMatch {
public static void main(String[] args) {
System.out.println(getFruitColor("apple")); // 红色
System.out.println(getFruitColor("banana")); // 黄色
System.out.println(getFruitColor("grape")); // 紫色
}
static String getFruitColor(String fruit) {
return switch (fruit.toLowerCase()) {
case "apple", "strawberry", "cherry" -> "红色";
case "banana", "lemon", "mango" -> "黄色";
case "grape", "plum", "berry" -> "紫色";
case "orange", "peach" -> "橙色";
default -> "未知颜色";
};
}
}
块级表达式(使用 yield)
当需要执行多条语句时,使用 yield 返回值:
public class BlockExpression {
public static void main(String[] args) {
System.out.println(evaluateGrade(85));
System.out.println(evaluateGrade(72));
System.out.println(evaluateGrade(45));
}
static String evaluateGrade(int score) {
return switch (score / 10) {
case 10, 9 -> {
if (score >= 95) {
yield "优秀 (A+)";
} else {
yield "优秀 (A)";
}
}
case 8 -> {
String grade = "良好 (B)";
if (score >= 85) {
grade = "良好 (B+)";
}
yield grade;
}
case 7 -> "中等 (C)";
case 6 -> "及格 (D)";
default -> {
if (score >= 0) {
yield "不及格 (F)";
} else {
yield "无效分数";
}
}
};
}
}
枚举类型使用
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public class EnumSwitch {
public static void main(String[] args) {
Day day = Day.SATURDAY;
System.out.println(isWeekend(day)); // true
System.out.println(getDayActivity(day)); // 享受周末时光
// 遍历所有枚举值
for (Day d : Day.values()) {
System.out.printf("%-10s: %s%n", d, getDayActivity(d));
}
}
static boolean isWeekend(Day day) {
return switch (day) {
case SATURDAY, SUNDAY -> true;
default -> false;
};
}
static String getDayActivity(Day day) {
return switch (day) {
case MONDAY -> "开始工作";
case TUESDAY, WEDNESDAY, THURSDAY -> "正常工作";
case FRIDAY -> "准备周末";
case SATURDAY -> "享受周末时光";
case SUNDAY -> "准备新的一周";
};
}
}
复杂业务逻辑
public class BusinessLogic {
public static void main(String[] args) {
// 订单状态处理
Order order1 = new Order("ORD001", 500, OrderStatus.PENDING);
System.out.println(processOrder(order1));
// 支付方式处理
String paymentResult = handlePayment("crypto", 1000);
System.out.println(paymentResult);
}
enum OrderStatus {
PENDING, CONFIRMED, SHIPPED, COMPLETED, CANCELLED
}
static class Order {
String id;
double amount;
OrderStatus status;
Order(String id, double amount, OrderStatus status) {
this.id = id;
this.amount = amount;
this.status = status;
}
}
static String processOrder(Order order) {
return switch (order.status) {
case PENDING -> {
double discount = order.amount > 500 ? 0.1 : 0.05;
yield String.format("订单 %s 待处理,可享受 %.0f%% 折扣", order.id, discount * 100);
}
case CONFIRMED -> "订单已确认,准备发货";
case SHIPPED -> "订单已发货,请等待收货";
case COMPLETED -> "订单已完成,感谢购买";
case CANCELLED -> "订单已取消";
};
}
// 多种支付方式处理
static String handlePayment(String method, double amount) {
return switch (method) {
case "alipay" -> "使用支付宝支付 " + amount + " 元";
case "wechat" -> "使用微信支付 " + amount + " 元";
case "credit" -> {
yield amount > 5000 ? "信用额度超限" : "使用信用卡支付 " + amount + " 元";
}
case "crypto" -> "使用加密货币支付 " + amount + " 元";
default -> "不支持的支付方式";
};
}
}
类型转换(使用模式匹配,Java 17+)
public class PatternMatchingDemo {
public static void main(String[] args) {
Object obj1 = "Hello Java 12";
Object obj2 = 42;
Object obj3 = 3.14;
System.out.println(describe(obj1));
System.out.println(describe(obj2));
System.out.println(describe(obj3));
}
// Java 17+ 支持类型模式匹配
static String describe(Object obj) {
return switch (obj) {
case Integer i -> "整数: " + i;
case String s && s.length() > 5 -> "长字符串: " + s;
case String s -> "短字符串: " + s;
case Double d -> "浮点数: " + d;
case null -> "空值";
default -> "其他类型: " + obj.getClass().getName();
};
}
}
实际应用场景
import java.time.DayOfWeek;
import java.time.LocalDate;
public class PracticalUse {
public static void main(String[] args) {
// 计算工资
int workingDays = 22;
double salary = calculateSalary(8000, workingDays, "senior");
System.out.printf("本月工资: %.2f 元%n", salary);
// 获取当天安排
System.out.println(getSchedule(LocalDate.now().getDayOfWeek()));
// 简单状态机
System.out.println(nextState("TO_DO"));
System.out.println(nextState("IN_PROGRESS"));
}
// 工资计算
static double calculateSalary(double base, int days, String level) {
return switch (level) {
case "junior" -> base * (days / 22.0) * 0.9;
case "mid" -> base * (days / 22.0) * 1.0;
case "senior" -> base * (days / 22.0) * 1.3;
case "manager" -> {
double bonus = days > 25 ? 2000 : 0;
yield base * (days / 22.0) * 1.5 + bonus;
}
default -> throw new IllegalArgumentException("未知级别: " + level);
};
}
// 获取当天安排
static String getSchedule(DayOfWeek day) {
return switch (day) {
case MONDAY -> "周一:工作例会";
case TUESDAY, THURSDAY -> "技术开发";
case WEDNESDAY -> "团队协作";
case FRIDAY -> "工作总结";
case SATURDAY -> "自由时间";
case SUNDAY -> "休息准备";
};
}
// 状态机
static String nextState(String currentState) {
return switch (currentState) {
case "TO_DO" -> "IN_PROGRESS";
case "IN_PROGRESS" -> "IN_REVIEW";
case "IN_REVIEW" -> "DONE";
case "DONE" -> "COMPLETED";
default -> currentState;
};
}
}
性能与便捷性对比
public class PerformanceComparison {
public static void main(String[] args) {
int num = 5000000;
// 传统 Switch 性能测试
long start1 = System.nanoTime();
long sum1 = 0;
for (int i = 0; i < num; i++) {
sum1 += traditionalSwitch(i % 4);
}
long end1 = System.nanoTime();
// Switch 表达式性能测试
long start2 = System.nanoTime();
long sum2 = 0;
for (int i = 0; i < num; i++) {
sum2 += switchExpression(i % 4);
}
long end2 = System.nanoTime();
System.out.printf("传统Switch: %d ms%n", (end1 - start1) / 1_000_000);
System.out.printf("Switch表达式: %d ms%n", (end2 - start2) / 1_000_000);
System.out.printf("结果相同: %b%n", sum1 == sum2);
}
// 传统方法
static int traditionalSwitch(int x) {
int result;
switch (x) {
case 0: result = 10; break;
case 1: result = 20; break;
case 2: result = 30; break;
case 3: result = 40; break;
default: result = 0; break;
}
return result;
}
// Switch 表达式
static int switchExpression(int x) {
return switch (x) {
case 0 -> 10;
case 1 -> 20;
case 2 -> 30;
case 3 -> 40;
default -> 0;
};
}
}
| 特性 | 描述 |
|---|---|
| 箭头语法 | -> 避免穿透,更清晰 |
| 多值匹配 | case 1, 2, 3 -> 简化代码 |
| 表达式返回值 | Switch 可作为表达式返回结果 |
| yield 关键字 | 在块中返回值 |
| 无变量作用域泄漏 | 每个 case 有独立作用域 |
| 无需 break | 箭头语法自动 break |
| 穷尽性检查 | 所有可能情况必须处理 |
注意事项
- 编译要求:Java 12+ 编译,若要在旧版本使用需加上
--release 12。 - 默认分支:对于枚举类型或非穷尽情况,可能需要
default。 - 返回值类型:所有分支必须返回相同类型。
这些案例展示了 Switch 表达式如何让代码更简洁、可读性更强,同时减少错误发生的可能性。