java14新特性-Switch表达式

java12新特性—Switch表达式(预览)

java 12作为一次小版本的更新,主要引入了一些语法层面的增强,其中包括Switch表达式。Switch表达式的引入使得处理多个分支的代码更加紧凑和可读性更高

Switch表达式的基本用法和语法规则

int result = switch (variable) {
case value1 -> expression1;
case value2 -> expression2;
case value3 -> {
// multiple expressions
expression3;
expression4;
// ...
yield expression5; // return the value of expression5
}
//...
default -> defaultExpression;
};

variable 是待比较的变量,value1、value2等是待匹配的值,expression1、expression2等是相应分支的表达式。如果需要返回结果,可以使用yield语句。
每个分支的结束需要使用->箭头符号
default表示默认分支

  • 与传统Switch语句的对比
// 传统Switch语句
int result1;
switch (variable) {
case value1:
result1 = expression1;
break;
case value2:
result1 = expression2;
break;
case value3:
result1 = expression3;
break;
// ...
default:
result1 = defaultExpression;
}
// Switch表达式
int result2 = switch (variable) {
case value1 -> expression1;
case value2 -> expression2;
case value3 -> expression3;
// ...
default -> defaultExpression;
};

相比传统的Switch语句,Switch表达式的好处在于简洁性和可读性的提升。传统的Switch语句需要使用大括号来限定每个分支的作用域,而Switch表达式省略了大括号,使代码更加简洁。另外,Switch表达式支持返回值,使得可以将结果直接赋值给变量,进一步简化代码。下面是一个简单的示例,比较传统Switch语句和Switch表达式的用法

Yield语句的使用

在Java 12版本中,Switch表达式引入了一个新的关键字:yield。它用于在Switch表达式中返回某个值,并将执行流程从Switch语句中退出

public static String getDayOfWeekName(int dayOfWeek) {
return switch (dayOfWeek) {
case 1 -> "Monday";
case 2 -> "Tuesday";
case 3 -> "Wednesday";
case 4 -> "Thursday";
case 5 -> "Friday";
case 6, 7 -> {
yield "Weekend";
}
default -> "Invalid day";
};
}

在上述示例中,当dayOfWeek为6或7时,代码块{ yield “Weekend”; }会被执行,并返回”Weekend”

箭头符号 -> 的嵌套使用

Switch表达式中的箭头符号 -> 可以进行嵌套使用,使得Switch表达式的逻辑更加清晰

public static String getGrade(int score) {
return switch (score) {
case 90 -> "A";
case 80 -> "B";
case 70 -> "C";
case 60 -> "D";
default -> {
if (score >= 0 && score < 60) {
yield "F";
} else {
yield "Invalid score";
}
}
};
}

在上述示例中,当score不属于90、80、70、60这四个值时,先通过if语句判断评分是否在0到60之间,如果是则返回”F”,否则返回”Invalid score”

多个表达式的合并使用

Java 12中引入了逗号运算符,可以在一个表达式中包含多个子表达式。在Switch表达式中的每个分支中,可以使用逗号运算符将多个表达式合并成一个,进一步简化代码

public static String getQuarter(int month) {
return switch (month) {
case 1, 2, 3 -> "Q1";
case 4, 5, 6 -> "Q2";
case 7, 8, 9 -> "Q3";
case 10, 11, 12 -> "Q4";
default -> "Invalid month";
};
}

在上述示例中,每个case后面的逗号运算符将多个月份合并成一个条件判断,并返回对应的季度。

java13新特性—Switch表达式(第二次预览)

Java 13对Switch表达式的优化和改进

  • case标签可以使用逗号分隔,实现多个值的单独处理
int score = 80;
switch (score) {
case 90, 100:
System.out.println("优秀");
break;
case 70, 80:
System.out.println("良好");
break;
case 60:
System.out.println("及格");
break;
default:
System.out.println("不及格");
break;
}
  • Switch表达式可以直接返回一个值,无需使用break语句
public String getGrade(int score) {
return switch (score) {
case 90, 100 -> "优秀";
case 70, 80 -> "良好";
case 60 -> "及格";
default -> "不及格";
};
}

新增的模式匹配功能

Java 13还引入了模式匹配的概念,在Switch表达式中使用模式匹配可以更方便地处理各种场景

public String getType(Object object) {
return switch (object) {
case Integer i -> "整数";
case Double d -> "浮点数";
case String s -> "字符串";
default -> "未知类型";
};
}

添加的空安全性校验

在Java 13中,Switch表达式还引入了空安全性校验,可以对空值进行处理。

public String getType(Object object) {
return switch (object) {
case Integer i -> "整数";
case Double d -> "浮点数";
case String s -> "字符串";
case null -> "空值";
default -> "未知类型";
};
}

应用

  • 使用Switch表达式进行功能分支的简化实现
// 示例:使用Switch表达式实现信用卡类型判断
public String getCardType(int score) {
return switch (score) {
case 0 -> "No Credit";
case 1, 2 -> "Basic";
case 3, 4 -> "Silver";
case 5, 6 -> "Gold";
default -> "Platinum";
};
}
  • 枚举类型的处理
// 示例:使用Switch表达式处理季节枚举类型
public String getSeason(Month month) {
return switch (month) {
case DECEMBER, JANUARY, FEBRUARY -> "Winter";
case MARCH, APRIL, MAY -> "Spring";
case JUNE, JULY, AUGUST -> "Summer";
case SEPTEMBER, OCTOBER, NOVEMBER -> "Autumn";
};
}
  • 字符串的匹配和处理
// 示例:使用Switch表达式处理网站用户角色字符串
public String getRoleDescription(String role) {
return switch (role) {
case "admin" -> "Administrator";
case "editor" -> "Content Editor";
case "user" -> "Regular User";
default -> "Unknown Role";
};
}

java14新特性—Switch表达式(正式)

Java 12 将表达式引入 Switch 语句并作为预览功能发布。 Java 13 添加了一个新的 yield 结构来从 switch 语句返回一个值。 在 Java14 中,switch 表达式现在是一项标准功能

在 Java 14 中,新的 switch 表达式主要改变了两个方面:

  1. 支持箭头表达式返回;
  2. 支持 yied 返回值。

语法

  • Java 14之前语法
import org.junit.Test;

enum Gender {
MALE, FEMALE, UNKNOWN;
}

public class TestX {
private Gender gender = Gender.MALE;

@Test
public void show() {
switch (gender) {
case MALE:
System.out.println("男");
break;
case FEMALE:
System.out.println("女");
break;
default:
throw new IllegalStateException(gender.toString());
break;
}
}
}
  • java14
@Test
public void show() {
switch (gender) {
case MALE -> System.out.println("男");
case FEMALE -> System.out.println("女");
default -> throw new IllegalStateException(gender.toString());
}
}

返回值

  • Java14 之前 switch 语法不支持返回值,需要通过一个中间变量来返回
import org.junit.Test;

enum Gender {
MALE, FEMALE, UNKNOWN;
}

public class TestX {
public String swi(Gender gender) {
String s;
switch (gender) {
case MALE:
s = "男";
break;
case FEMALE:
s = "女";
break;
default:
throw new IllegalStateException(gender.toString());
}
return s;
}

@Test
public void show() {
String s = swi(Gender.UNKNOWN);
}
}
  • Java14 switch 表达式返回值
public String swi(Gender gender) {
String s = switch (gender) {
case MALE -> "男";
case FEMALE -> "女";
default -> throw new IllegalStateException(gender.toString());
};
}

yield 返回值

yield 和 return 的区别在于:return 会直接跳出当前循环或者方法,而 yield 只会跳出当前 switch 块

public String swi(Gender gender) {
String s = switch (gender) {
case MALE -> "男";
case FEMALE -> "女";
default -> {
yield "未知";
}
};
}

新的 switch 表达式在旧的 JDK 版本中无法兼容,而且字节码文件反编译后也是旧的 switch 格式,所以不推荐使用新的 switch 表达式