概述

  1. Java 模式匹配是一个新型的、而且还在持续快速演进的领域
  2. 类型匹配模式匹配的一个规范,在 JDK 16 正式发布
  3. 一个模式是匹配谓词匹配变量的组合
    • 匹配谓词用来确定模式目标是否匹配
    • 在模式和目标匹配的情况下,匹配变量是从匹配目标提取出来的一个或者多个变量
  4. 对于类型匹配来说,匹配谓词用来指定模式数据类型,而匹配变量就是属于该类型数据变量
    • 对于类型匹配来说,匹配变量只有一个

模式

1
2
3
4
5
6
7
8
static boolean isSquare(Shape shape) {
if (shape instanceof Rectangle) {
Rectangle rect = (Rectangle) shape;
return (rect.length == rect.width);
}

return (shape instanceof Square);
}

模式拆分 - 类型判断 + 类型转换 - 增加出错概率

  1. 类型判断语句 - 匹配谓词
  2. 类型转换语句
  3. 声明一个新的本地变量,即匹配变量,来承载转换后的数据

类型匹配

1
2
3
if (shape instanceof Rectangle rect) {
return (rect.length == rect.width);
}

image-20250803234618210

使用类型匹配的代码,只有匹配谓词本地变量两部分,并且在同一个语句

image-20250803234809565

  1. 如果目标变量是一个长方形的实例,那么这个目标变量就会被赋值给一个本地的长方形变量,即匹配变量,否则不会被赋值
  2. Java 编译器不允许使用没有赋值的匹配变量

image-20250803235537533

image-20250803235730105

使用匹配变量的条件语句 else 分支并没有声明这个匹配变量 - 作用域 - 类型匹配的关键

匹配变量的作用域

只有明确匹配,才能使用

  1. 匹配变量的作用域,就是目标变量可以被确认匹配的范围
    • 如果在一个范围内,无法确认目标变量是否被匹配,或者目标变量不能被匹配,都不能使用目标变量
  2. 编译器角度 - 在一个范围里,如果编译器能够确定匹配变量已经被赋值,那么它就可以在这个范围内使用
    • 如果编译器无法确定匹配变量是否被赋值,或者确定没有被赋值,那么它就不能在这个范围内使用

Case 1

1
2
3
4
5
6
7
8
9
public static boolean isSquare(Shape shape) {
if (shape instanceof Rectangle rectangle) {
// rectangle is in scope
return rectangle.length == rectangle.width;
}

// rectangle is out of scope
return shape instanceof Square;
}

Case 2

1
2
3
4
5
6
7
8
public static boolean isSquare(Shape shape) {
if (!(shape instanceof Rectangle rectangle)) {
// rectangle is out of scope
return shape instanceof Square;
}
// rectangle is in scope
return rectangle.length == rectangle.width;
}

Case 3

1
2
3
4
public static boolean isSquare(Shape shape) {
return shape instanceof Square
|| shape instanceof Rectangle rectangle && rectangle.length == rectangle.width;
}

Case 4

类型不匹配,才能进行下一步运算,即编译器明确知道匹配变量没有被赋值

image-20250804001605767

Case 5

& 运算符两侧的表达式都要参与计算 - 无论左侧的类型匹配与否,右侧的匹配变量都要使用 - 违反了匹配变量的作用域原则 - 编译器无法确认匹配变量是否被赋值

image-20250804001843882

Case 6

  1. 定义了一个静态变量,它和匹配变量同名
  2. 匹配变量作用域内,除非特殊处理,否则这个静态变量就被遮掩住了 - 影子变量 - Shadowed Variable

image-20250804002405846

性能提升

20%

1
2
3
Benchmark                 Mode  Cnt          Score          Error  Units
PatternBench.useCast thrpt 15 263559326.599 ± 78815341.366 ops/s
PatternBench.usePattern thrpt 15 313458467.044 ± 2666412.767 ops/s