乐途乐途
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
  • 学习路径
  • 第1章 Java概述与环境搭建

    • Java概述与环境搭建
    • Java语言概述
    • 解释型语言与编译型语言对比
    • JDK安装与配置
    • JDK、JRE、JVM 详解
    • HelloWorld程序详解
    • IDE 介绍
  • 第2章 标识符与基本数据类型

    • 章节导读
    • 变量概述
    • 常量概述
    • 基本类型与包装类
    • 字节型 byte
    • 短整型 short
    • 整型 int
    • 长整型 long
    • 单精度浮点型 float
    • 双精度浮点型 double
    • 字符型 char
    • 布尔型 boolean
    • 类型转换
  • 第3章 运算符与表达式

    • 章节导读
    • 算术运算符
    • 赋值运算符
    • 关系运算符
    • 逻辑运算符
    • 位运算符
    • 条件运算符
    • 运算符优先级
    • 表达式
  • 第4章 流程控制

    • 章节导读
    • 常见的程序运行流程
    • if-else 选择结构
    • switch 多分支选择
    • while 循环
    • do-while 循环
    • for 循环
    • break 与 continue
  • 第5章 数组

    • 章节导读
    • 一维数组
    • 多维数组
    • Arrays 工具类
  • 第6章 类与对象

    • 章节导读
    • 类与对象
    • 方法定义与调用
    • 构造方法
    • 封装
    • 访问修饰符
    • package 与 import
    • static 关键字
    • this 关键字
    • 参数传递 详解
    • 枚举
    • 成员内部类
    • 局部内部类
    • 静态内部类
    • 匿名内部类
  • 第7章 接口与继承

    • 章节导读
    • 继承
    • super 关键字
    • final 关键字
    • 多态
    • 向上转型与向下转型
    • 抽象类
    • 接口
    • 抽象类与接口对比
  • 第8章 注解

    • 章节导读
    • 注解基础
    • 元注解详解
    • 自定义注解
  • 第9章 常用类

    • 章节导读:Java 常用类
    • Object 类:万类之祖
    • 包装类:基本类型的对象化
    • String:不可变的字符串
    • StringBuffer:线程安全的可变字符串
    • StringBuilder:可变的字符串构建器
    • Math:数学运算工具类
    • Random:伪随机数生成器
    • 大数值运算 详解
    • 日期时间API 详解
  • 第10章 异常机制

    • 章节导读
    • 异常体系与分类
    • try-catch-finally
    • try-with-resources
    • throws 与 throw
    • 自定义异常
  • 第11章 泛型

    • 章节导读
    • 泛型基础
    • 通配符与PECS原则
    • 类型擦除
  • 第12章 集合框架

    • 章节导读
    • 集合框架概述
    • ArrayList
    • LinkedList
    • HashMap 详解
    • LinkedHashMap 详解
    • TreeMap 详解
    • HashSet
    • TreeSet 详解
    • TreeSet 与 Comparable
    • Collections 工具类详解
  • 第13章 IO流

    • 章节导读
    • IO流概述
    • 字节流
    • 字符流
    • 缓冲流
    • 转换流 详解
    • 序列化 详解
    • NIO与Files 详解
    • NIO与Files工具类
  • 第14章 多线程与并发

    • 第十六章 多线程与并发 —— 章节导读
    • 线程基础详解
    • synchronized 详解
    • Lock 与显式锁详解
    • volatile 详解
    • wait 与 notify 详解
    • ThreadLocal详解
    • 原子类详解
    • 并发工具类详解
    • 线程池详解
  • 第15章 反射

    • 章节导读
    • 反射概述与 Class 对象
    • Constructor 与对象创建
    • Field与Method详解
    • 反射应用详解
  • 第16章 JDK8新特性

    • 章节导读
    • Lambda 表达式
    • Stream API 基础
    • Stream API 高级详解
    • Optional 详解
    • 新日期时间API详解
  • 第17章 JDK9-11新特性

    • 章节导读
    • 模块化系统 — Project Jigsaw(JDK 9)
    • var 局部变量类型推断(JDK 10)
    • 集合工厂方法与增强(JDK 9 / 10 / 11)
    • 接口增强:private 方法(JDK 9)
    • Stream API 增强(JDK 9)
    • Optional 增强(JDK 9 / 10 / 11)
    • String 新增方法(JDK 11)
    • HTTP Client 与 Files 增强(JDK 11)
    • 直接运行 Java 源文件 — JEP 330(JDK 11)
  • 第18章 JDK12-17新特性

    • 章节导读
    • Switch 表达式(JDK 12 预览 / JDK 14 正式)
    • 文本块 Text Blocks(JDK 13 预览 / JDK 15 正式)
    • Records 记录类(JDK 14 预览 / JDK 16 正式)
    • 密封类 Sealed Classes(JDK 15 预览 / JDK 17 正式)
    • instanceof 模式匹配(JDK 14 预览 / JDK 16 正式)
    • Switch 模式匹配 — Pattern Matching for switch(JDK 17 预览 / JDK 21 正式)
    • Helpful NPE 与 String 增强(JDK 12 / JDK 14 / JDK 15)
    • Stream 增强(JDK 12 / JDK 16)
    • 日期时间增强 — Day Period 支持(JDK 16)
  • 第19章 JDK18-21新特性

    • 章节导读
    • 虚拟线程(JDK 19 预览 / JDK 20 第二预览 / JDK 21 正式)
    • 序列集合(JDK 21 正式)
    • Switch 模式匹配(JDK 17 预览 / JDK 18 第二预览 / JDK 20 第四预览 / JDK 21 正式)
    • Record 模式匹配(JDK 19 预览 / JDK 20 第二预览 / JDK 21 正式)
    • 未命名模式与变量(JDK 21 预览 / JDK 22 正式)
  • 第20章 JDK 22-25 新特性

    • 章节导读
    • 字符串模板(JDK 22 预览 / JDK 23 第二预览 / JDK 24 第三预览)
    • Stream Gatherers(JDK 22 预览 / JDK 24 第二预览)
    • 隐式声明类与实例方法(JDK 23 预览 / JDK 24 第二预览)
    • 原始类型模式匹配(JDK 24 预览)
  • 附录

    • Java 核心知识点
    • Java SE 专业术语
    • Java特性索引(JDK 8 → 25)

Record 模式匹配(JDK 19 预览 / JDK 20 第二预览 / JDK 21 正式)

大翔(CTO):"小崔,咱们飞翔科技的订单审计系统最近处理日志的时候,是不是写了一堆 instanceof 判断后再强转的代码?"

小崔(后端开发):"是啊大翔,每个 OrderEvent 都要先判断类型,再一个个 getXxx() 取字段,代码又臭又长。"

白歌(架构师):"JDK 21 的 Record 模式匹配就是为解决这个问题而生的。你可以在 instanceof 和 switch 里直接解构 Record,一行代码搞定类型判断和字段提取。"

孔蓝(后端新人):"这么神奇?那嵌套的 Record 也能直接解构吗?"

什么是 Record 模式匹配

概念说明
Record 模式匹配在 instanceof 或 switch 中直接解构 Record 对象,提取其组件值并绑定到变量
解构将 Record 对象的组件值直接分解为多个变量的过程
模式变量在模式中声明的变量,仅在匹配成功后才会初始化并可用
嵌套模式在 Record 模式中嵌套另一个 Record 模式,实现深层解构

演进关系

基础语法:instanceof + Record 模式匹配

传统写法 vs Record 模式匹配

// === 场景说明 ===
// 传统写法:需要先 instanceof 判断,再强制类型转换,最后调用访问器方法

import java.math.BigDecimal;
import java.time.Instant;

record Point(int x, int y) {}
record Customer(String name, String email) {}
record OrderEvent(String orderId, BigDecimal amount, Instant timestamp, Customer customer) {}

public class RecordPatternDemo {
    public static void main(String[] args) {
        Object obj = new Point(10, 20);
        
        // 传统写法
        if (obj instanceof Point) {
            Point p = (Point) obj;
            int x = p.x();
            int y = p.y();
            System.out.println("点坐标: (" + x + ", " + y + ")");
        }
        
        // ✅ Record 模式匹配:直接解构
        if (obj instanceof Point(int x, int y)) {
            System.out.println("点坐标: (" + x + ", " + y + ")");
        }
    }
}

输出:

点坐标: (10, 20)
点坐标: (10, 20)

核心优势

对比维度传统写法Record 模式匹配
代码行数5-6 行1 行
类型转换需要强制转换自动解构
变量作用域外部作用域模式内作用域
空安全需手动检查模式匹配保证

switch + Record 模式匹配

基础用法

// === 场景说明 ===
// 在 switch 表达式中使用 Record 模式匹配,根据 Point 的坐标值进行不同处理

public class RecordPatternDemo {
    sealed interface Shape permits Circle, Rectangle, Point {}
    record Circle(double radius) implements Shape {}
    record Rectangle(double width, double height) implements Shape {}
    record Point(int x, int y) implements Shape {}
    
    public static String describeShape(Shape shape) {
        return switch (shape) {
            case Circle(double r) -> "圆形,半径: " + r;
            case Rectangle(double w, double h) -> "矩形,宽: " + w + ", 高: " + h;
            case Point(int x, int y) when x == y -> "点在对角线上: (" + x + ", " + y + ")";
            case Point(int x, int y) -> "点: (" + x + ", " + y + ")";
        };
    }
    
    public static void main(String[] args) {
        System.out.println(describeShape(new Circle(5.0)));
        System.out.println(describeShape(new Rectangle(3.0, 4.0)));
        System.out.println(describeShape(new Point(5, 5)));
        System.out.println(describeShape(new Point(3, 7)));
    }
}

输出:

圆形,半径: 5.0
矩形,宽: 3.0, 高: 4.0
点在对角线上: (5, 5)
点: (3, 7)

流程图

嵌套 Record 模式匹配

深层解构

// === 场景说明 ===
// 嵌套 Record 模式匹配:直接解构 OrderEvent -> Customer -> Address 的嵌套结构

import java.math.BigDecimal;
import java.time.Instant;

record Address(String city, String street) {}
record Customer(String name, Address address) {}
record OrderEvent(String orderId, BigDecimal amount, Instant timestamp, Customer customer) {}

public class NestedRecordPattern {
    public static String getOrderCity(OrderEvent event) {
        // ✅ 嵌套解构:直接提取深层字段
        if (event instanceof OrderEvent(String id, BigDecimal amt, Instant ts, 
                                       Customer(String name, Address(String city, String street)))) {
            return city;
        }
        return "未知";
    }
    
    public static String processOrder(OrderEvent event) {
        return switch (event) {
            case OrderEvent(String id, BigDecimal amt, Instant ts,
                           Customer(String name, Address(String city, _))) 
                when city.equals("北京") -> "北京订单: " + id;
            case OrderEvent(String id, BigDecimal amt, _, Customer(String name, _)) 
                when amt.compareTo(new BigDecimal("10000")) > 0 -> "大额订单: " + id;
            default -> "普通订单";
        };
    }
    
    public static void main(String[] args) {
        OrderEvent event = new OrderEvent(
            "ORD-001",
            new BigDecimal("5000"),
            Instant.now(),
            new Customer("张三", new Address("北京", "朝阳路"))
        );
        
        System.out.println("订单城市: " + getOrderCity(event));
        System.out.println("订单处理: " + processOrder(event));
    }
}

输出:

订单城市: 北京
订单处理: 北京订单: ORD-001

嵌套解构流程图

var 在模式匹配中的使用

类型推断

// === 场景说明 ===
// 使用 var 进行类型推断,让编译器自动推断 Record 组件的类型

import java.math.BigDecimal;
import java.time.Instant;

record Point(int x, int y) {}
record OrderEvent(String orderId, BigDecimal amount, Instant timestamp, String status) {}

public class RecordPatternDemo {
    public static void main(String[] args) {
        Object obj = new Point(10, 20);
        
        // ✅ 使用 var:编译器自动推断类型
        if (obj instanceof Point(var x, var y)) {
            System.out.println("点坐标: (" + x + ", " + y + ")");
            // x 和 y 的类型被推断为 int
        }
        
        Object event = new OrderEvent("ORD-001", new BigDecimal("999.99"), 
                                      Instant.now(), "PAID");
        
        // ✅ switch + var:灵活处理不同类型
        String result = switch (event) {
            case OrderEvent(var id, var amount, var time, var status) 
                when status.equals("PAID") -> "已支付订单: " + id;
            case Point(var x, var y) -> "点: (" + x + ", " + y + ")";
            default -> "未知类型";
        };
        
        System.out.println(result);
    }
}

输出:

点坐标: (10, 20)
已支付订单: ORD-001

var 的优势

场景优势
复杂类型避免手写冗长的泛型类型
代码重构Record 组件类型变更时无需修改模式
可读性聚焦业务逻辑而非类型声明

实战场景:飞翔科技订单审计系统

业务背景

飞翔科技的订单审计系统需要处理海量订单事件,识别异常订单并进行实时告警。

// === 场景说明 ===
// 实战:订单审计系统中的异常检测,使用 Record 模式匹配直接解构订单事件

import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;

record Address(String city, String street) {}
record Customer(String name, String level, Address address) {}
record OrderEvent(String orderId, BigDecimal amount, Instant timestamp, 
                  Customer customer, String eventType) {}

public class OrderAuditSystem {
    
    // 审计日志处理:直接解构 OrderEvent
    public static void processAuditLog(Object logEntry) {
        if (logEntry instanceof OrderEvent(String orderId, BigDecimal amount, 
                                          Instant timestamp, Customer customer, 
                                          String eventType)) {
            System.out.println("审计日志 - 订单ID: " + orderId);
            System.out.println("  金额: " + amount);
            System.out.println("  客户: " + customer.name());
            System.out.println("  事件类型: " + eventType);
        }
    }
    
    // 异常检测:嵌套解构 + 模式匹配
    public static String detectAnomaly(OrderEvent event) {
        return switch (event) {
            // 大额订单且客户为 VIP
            case OrderEvent(var id, var amount, _, 
                           Customer(var name, "VIP", _), "CREATE") 
                when amount.compareTo(new BigDecimal("50000")) > 0 
                -> "⚠️ 高危: VIP客户大额新订单 - " + id;
            
            // 异地订单
            case OrderEvent(var id, _, _, 
                           Customer(_, _, Address(city, _)), "CREATE") 
                when !city.equals("北京") && !city.equals("上海") 
                -> "⚠️ 注意: 异地订单 - " + id;
            
            // 取消的已支付订单
            case OrderEvent(var id, var amount, _, _, "CANCEL") 
                when amount.compareTo(new BigDecimal("1000")) > 0 
                -> "⚠️ 损失: 大额已支付订单取消 - " + id;
            
            default -> "✅ 正常";
        };
    }
    
    public static void main(String[] args) {
        List<OrderEvent> events = List.of(
            new OrderEvent("ORD-001", new BigDecimal("60000"), Instant.now(),
                           new Customer("张三", "VIP", new Address("北京", "朝阳路")), "CREATE"),
            new OrderEvent("ORD-002", new BigDecimal("3000"), Instant.now(),
                           new Customer("李四", "NORMAL", new Address("成都", "天府大道")), "CREATE"),
            new OrderEvent("ORD-003", new BigDecimal("2000"), Instant.now(),
                           new Customer("王五", "NORMAL", new Address("上海", "南京路")), "CANCEL")
        );
        
        for (OrderEvent event : events) {
            processAuditLog(event);
            System.out.println("  异常检测: " + detectAnomaly(event));
            System.out.println("---");
        }
    }
}

输出:

审计日志 - 订单ID: ORD-001
  金额: 60000
  客户: 张三
  事件类型: CREATE
  异常检测: ⚠️ 高危: VIP客户大额新订单 - ORD-001
---
审计日志 - 订单ID: ORD-002
  金额: 3000
  客户: 李四
  事件类型: CREATE
  异常检测: ⚠️ 注意: 异地订单 - ORD-002
---
审计日志 - 订单ID: ORD-003
  金额: 2000
  客户: 王五
  事件类型: CANCEL
  异常检测: ⚠️ 损失: 大额已支付订单取消 - ORD-003
---

系统架构流程图

record + sealed class + switch 三件套

组合威力

// === 场景说明 ===
// record + sealed class + switch 模式匹配:构建类型安全的领域模型

import java.math.BigDecimal;

// sealed class 定义封闭的继承层次
sealed interface Payment permits WeChatPay, Alipay, BankCardPay, ApplePay {}

// record 定义不可变数据载体
        System.out.println(processPayment(p1));
        System.out.println(processPayment(p2));
        System.out.println(processPayment(p3));
        System.out.println(processPayment(p4));
    }
}

输出:

微信支付 [交易ID: WX123456, 金额: 199.99]
支付宝支付 [交易号: ALI789012, 金额: 299.50]
银行卡支付 [卡号后4位: 7890, 银行: 工商银行, 金额: 999.00]
Apple Pay [Token: AP-Pay..., 金额: 499.00]

三件套威力分析

特性作用优势
sealed class限制继承层次编译器保证 switch exhaustive
record不可变数据载体自动生成 equals、hashCode、toString,支持解构
switch 模式匹配模式匹配 + 解构一行代码完成类型判断和字段提取

与未命名模式 _ 的结合

初步使用

// === 场景说明 ===
// 使用未命名模式 _ 忽略不需要的 Record 组件

import java.math.BigDecimal;
import java.time.Instant;

record OrderEvent(String orderId, BigDecimal amount, Instant timestamp, String status) {}

public class UnnamedPatternDemo {
    public static void main(String[] args) {
        OrderEvent event = new OrderEvent("ORD-001", new BigDecimal("999.99"), 
                                          Instant.now(), "PAID");
        
        // ✅ 使用 _ 忽略不需要的组件
        if (event instanceof OrderEvent(var id, _, _, "PAID")) {
            System.out.println("已支付订单: " + id);
        }
        
        // ✅ switch 中使用 _ 忽略组件
        String result = switch (event) {
            case OrderEvent(var id, _, _, "PAID") -> "订单已支付: " + id;
            case OrderEvent(var id, _, _, "CANCELLED") -> "订单已取消: " + id;
            case OrderEvent(var id, var amount, _, _) 
                when amount.compareTo(new BigDecimal("1000")) > 0 -> "大额订单: " + id;
            default -> "其他状态";
        };
        
        System.out.println(result);
    }
}

输出:

已支付订单: ORD-001
订单已支付: ORD-001

注意:未命名模式 _ 在 JDK 21 中作为预览特性引入,需要在编译和运行时使用 --enable-preview 参数。详细用法将在《未命名模式》文档中展开。

易错场景

1. 模式变量作用域错误

// === 场景说明 ===
// 错误:在模式匹配外部使用模式变量

public class RecordPatternError {
    public static void main(String[] args) {
        Object obj = new Point(10, 20);
        
        // ❌ 错误:模式变量 x, y 仅在 if 块内有效
        if (obj instanceof Point(int x, int y)) {
            System.out.println("点坐标: (" + x + ", " + y + ")");
        }
        // System.out.println(x);  // 编译错误:x 找不到符号
        
        // ✅ 正确:在模式匹配块内使用模式变量
        if (obj instanceof Point(int x, int y)) {
            System.out.println("点坐标: (" + x + ", " + y + ")");
            int sum = x + y;  // 正确:在作用域内使用
            System.out.println("坐标和: " + sum);
        }
    }
}

2. switch 模式匹配顺序错误

// === 场景说明 ===
// 错误:switch 分支顺序不当,导致代码不可达

record Point(int x, int y) {}

public class RecordPatternError {
    public static String describePoint(Point p) {
        // ❌ 错误:具体条件分支应放在前面
        return switch (p) {
            case Point(int x, int y) -> "点: (" + x + ", " + y + ")";
            // 下面这行代码不可达,编译错误
            // case Point(int x, int y) when x == y -> "点在对角线上";
        };
        
        // ✅ 正确:具体条件分支放在前面
        return switch (p) {
            case Point(int x, int y) when x == y -> "点在对角线上: (" + x + ", " + y + ")";
            case Point(int x, int y) -> "点: (" + x + ", " + y + ")";
        };
    }
}

3. 嵌套解构类型不匹配

// === 场景说明 ===
// 错误:嵌套解构时类型不匹配

record Inner(int value) {}
record Outer(Inner inner) {}

public class RecordPatternError {
    public static void main(String[] args) {
        Object obj = new Outer(new Inner(42));
        
        // ❌ 错误:嵌套解构类型不匹配
        // if (obj instanceof Outer(String s)) {  // 编译错误:Inner 不能匹配 String
        //     System.out.println(s);
        // }
        
        // ✅ 正确:嵌套解构类型匹配
        if (obj instanceof Outer(Inner(int value))) {
            System.out.println("内部值: " + value);
        }
        
        // ✅ 正确:使用 var 进行类型推断
        if (obj instanceof Outer(Inner(var v))) {
            System.out.println("内部值: " + v);
        }
    }
}

面试考点

问题 1:Record 模式匹配相比于传统的 instanceof + 强制类型转换有哪些优势?

答案:

  1. 代码简洁:传统写法需要 5-6 行代码(instanceof 判断 + 强制转换 + 调用访问器方法),而 Record 模式匹配只需 1 行。

  2. 作用域安全:模式变量的作用域仅限于匹配成功的块内,避免了变量泄露到外部作用域的风险。

  3. 类型安全:编译器在编译时检查类型匹配,避免了运行时 ClassCastException 的风险。

  4. 空安全:模式匹配保证只有在类型匹配成功时才会解构,避免了 NullPointerException。

  5. 可读性强:一眼就能看出代码意图,直接看到解构后的变量名。

问题 2:record + sealed class + switch 三件套组合有什么威力?为什么它们被称为"三件套"?

答案:

这三者的组合被称为"三件套",因为它们共同构建了一个类型安全的领域模型:

  1. sealed class:限制继承层次,编译器知道所有子类,保证 switch 表达式是 exhaustive 的(无需 default 分支)。

  2. record:不可变数据载体,自动生成 equals、hashCode、toString,最重要的是支持解构,可以在模式匹配中直接提取组件值。

  3. switch 模式匹配:在 switch 中直接使用模式匹配,一行代码完成类型判断和字段提取,编译器进行 exhaustiveness 检查。

威力体现:

  • 编译时类型安全检查,无需运行时类型判断
  • 无需 default 分支,新增子类时编译器会提示补充 case
  • 代码极其简洁,表达力强
sealed interface Expr permits Add, Mul, Num {}
record Add(Expr left, Expr right) implements Expr {}
record Mul(Expr left, Expr right) implements Expr {}
record Num(int value) implements Expr {}

int eval(Expr e) {
    return switch (e) {
        case Num(int v) -> v;
        case Add(Expr l, Expr r) -> eval(l) + eval(r);
        case Mul(Expr l, Expr r) -> eval(l) * eval(r);
    };
}

问题 3:嵌套 Record 模式匹配的解构过程是怎样的?有什么注意事项?

答案:

解构过程:

  1. 外层 Record 类型匹配成功
  2. 编译器自动调用外层 Record 的访问器方法获取内层 Record
  3. 对内层 Record 进行类型匹配和解构
  4. 将所有解构出的变量绑定到模式变量

注意事项:

  1. 类型必须匹配:嵌套解构时,内层类型必须与实际类型匹配。

  2. 可以使用 _ 忽略组件:不需要的组件可以用 _ 忽略。

  3. 可以使用 var 推断类型:不确定类型时可以使用 var 让编译器自动推断。

  4. 解构深度没有限制:可以嵌套多层解构,但建议不要超过 3 层,否则影响可读性。

// 多层嵌套解构
if (obj instanceof OrderEvent(var id, var amount, _, 
                              Customer(var name, _, 
                                       Address(var city, _)))) {
    System.out.println("订单: " + id + ", 客户: " + name + ", 城市: " + city);
}

总结

Record 模式匹配是 JDK 21 中的一个重要特性,它让 Java 在模式匹配方面迈出了重要一步。通过 instanceof 和 switch 中的直接解构,我们可以写出更简洁、更安全的代码。

结合 sealed class 和 record,我们可以构建出类型安全的领域模型,让编译器帮助我们进行类型检查,减少运行时错误。

白歌(架构师):"Record 模式匹配不仅仅是语法糖,它改变了我们处理数据的方式。从繁琐的类型判断和强制转换,到简洁的模式匹配和解构,这是 Java 语言现代化的重要一步。"

大翔(CTO):"没错,而且在飞翔科技的订单审计系统中,使用 Record 模式匹配后,代码量减少了一半,可读性也大大提升。这就是技术进步带来的实际价值。"

孔蓝(后端新人):"我现在明白了!以后处理复杂的数据结构,我会优先考虑使用 Record + 模式匹配的组合。"

小崔(后端开发):"我要赶紧把订单审计系统的代码重构一下,用上这些新特性!"


编程名言:"Simplicity is the soul of efficiency." — Austin Freeman

简约是效率的灵魂。

上一页
Switch 模式匹配(JDK 17 预览 / JDK 18 第二预览 / JDK 20 第四预览 / JDK 21 正式)
下一页
未命名模式与变量(JDK 21 预览 / JDK 22 正式)