# Java 17 新特性解析:记录类与密封类的实战应用指南

## 记录类(Records)的实战应用

### 基础语法与特性

```java

// 声明一个记录类

public record User(String name, String email, int age) {

// 编译器自动生成:

// - 所有字段的final访问器

// - 规范的构造函数

// - equals()、hashCode()、toString()方法

}

// 使用示例

public class RecordExample {

public static void main(String[] args) {

User user = new User(张三, zhangsan@example.com, 25);

System.out.println(user.name()); // 访问器方法

System.out.println(user.toString()); // 自动生成的toString

}

}

```

### 自定义记录类行为

```java

public record Product(String id, String name, double price) {

// 紧凑构造函数 - 用于数据验证

public Product {

if (price < 0) {

throw new IllegalArgumentException(价格不能为负数);

}

if (name == null || name.trim().isEmpty()) {

throw new IllegalArgumentException(产品名称不能为空);

}

}

// 添加自定义方法

public String displayInfo() {

return String.format(产品: %s, 价格: ¥%.2f, name, price);

}

// 静态方法

public static Product createDefault() {

return new Product(default, 默认产品, 0.0);

}

}

```

### 记录类在DTO模式中的应用

```java

// API响应DTO

public record ApiResponse(boolean success, String message, T data, long timestamp) {

public ApiResponse {

timestamp = System.currentTimeMillis();

}

public static ApiResponse success(T data) {

return new ApiResponse<>(true, 操作成功, data, System.currentTimeMillis());

}

public static ApiResponse error(String message) {

return new ApiResponse<>(false, message, null, System.currentTimeMillis());

}

}

// 使用示例

public class ApiClient {

public ApiResponse getUser(String userId) {

try {

User user = userService.findById(userId);

return ApiResponse.success(user);

} catch (Exception e) {

return ApiResponse.error(获取用户失败: + e.getMessage());

}

}

}

```

## 密封类(Sealed Classes)的实战应用

### 基础密封类定义

```java

// 定义密封类

public sealed abstract class Shape

permits Circle, Rectangle, Triangle {

public abstract double area();

public abstract double perimeter();

}

// 许可的子类

public final class Circle extends Shape {

private final double radius;

public Circle(double radius) {

this.radius = radius;

}

@Override

public double area() {

return Math.PI radius radius;

}

@Override

public double perimeter() {

return 2 Math.PI radius;

}

}

public final class Rectangle extends Shape {

private final double width;

private final double height;

public Rectangle(double width, double height) {

this.width = width;

this.height = height;

}

@Override

public double area() {

return width height;

}

@Override

public double perimeter() {

return 2 (width + height);

}

}

public non-sealed class Triangle extends Shape {

private final double base;

private final double height;

public Triangle(double base, double height) {

this.base = base;

this.height = height;

}

@Override

public double area() {

return 0.5 base height;

}

@Override

public double perimeter() {

// 简化计算

return base + height + Math.sqrt(base base + height height);

}

}

```

### 密封接口与模式匹配

```java

// 密封接口

public sealed interface PaymentMethod

permits CreditCard, PayPal, BankTransfer {

boolean processPayment(double amount);

}

public record CreditCard(String cardNumber, String expiryDate) implements PaymentMethod {

@Override

public boolean processPayment(double amount) {

// 信用卡处理逻辑

System.out.println(处理信用卡支付: + amount);

return true;

}

}

public record PayPal(String email) implements PaymentMethod {

@Override

public boolean processPayment(double amount) {

// PayPal处理逻辑

System.out.println(处理PayPal支付: + amount);

return true;

}

}

public record BankTransfer(String accountNumber) implements PaymentMethod {

@Override

public boolean processPayment(double amount) {

// 银行转账逻辑

System.out.println(处理银行转账: + amount);

return true;

}

}

```

### 结合switch表达式使用密封类

```java

public class PaymentProcessor {

public String process(PaymentMethod payment, double amount) {

return switch (payment) {

case CreditCard card -> {

boolean success = card.processPayment(amount);

yield success ? 信用卡支付成功 : 信用卡支付失败;

}

case PayPal paypal -> {

boolean success = paypal.processPayment(amount);

yield success ? PayPal支付成功 : PayPal支付失败;

}

case BankTransfer transfer -> {

boolean success = transfer.processPayment(amount);

yield success ? 银行转账成功 : 银行转账失败;

}

// 不需要default分支,因为所有情况都已覆盖

};

}

// 计算图形面积 - 使用模式匹配

public static String describeShape(Shape shape) {

return switch (shape) {

case Circle c -> String.format(圆形 - 半径: %.2f, 面积: %.2f,

c.radius(), c.area());

case Rectangle r -> String.format(矩形 - 宽: %.2f, 高: %.2f, 面积: %.2f,

r.width(), r.height(), r.area());

case Triangle t -> String.format(三角形 - 底: %.2f, 高: %.2f, 面积: %.2f,

t.base(), t.height(), t.area());

};

}

}

```

## 记录类与密封类的结合应用

### 领域建模示例

```java

// 定义领域事件密封类

public sealed interface DomainEvent

permits UserRegistered, UserUpdated, UserDeleted {

String aggregateId();

long timestamp();

}

public record UserRegistered(String userId, String email, String username)

implements DomainEvent {

@Override

public String aggregateId() { return userId; }

@Override

public long timestamp() { return System.currentTimeMillis(); }

}

public record UserUpdated(String userId, String oldEmail, String newEmail)

implements DomainEvent {

@Override

public String aggregateId() { return userId; }

@Override

public long timestamp() { return System.currentTimeMillis(); }

}

public record UserDeleted(String userId, String reason)

implements DomainEvent {

@Override

public String aggregateId() { return userId; }

@Override

public long timestamp() { return System.currentTimeMillis(); }

}

// 事件处理器

public class EventHandler {

public void handle(DomainEvent event) {

switch (event) {

case UserRegistered registered ->

System.out.println(用户注册: + registered.username());

case UserUpdated updated ->

System.out.println(用户更新: + updated.aggregateId());

case UserDeleted deleted ->

System.out.println(用户删除: + deleted.reason());

}

}

}

```

### 配置系统设计

```java

// 配置类层次结构

public sealed interface Config

permits DatabaseConfig, ApiConfig, CacheConfig {}

public record DatabaseConfig(

String url,

String username,

String password,

int poolSize

) implements Config {}

public record ApiConfig(

String baseUrl,

int timeout,

int retryAttempts

) implements Config {}

public record CacheConfig(

String redisHost,

int redisPort,

int ttl

) implements Config {}

// 配置管理器

public class ConfigManager {

private final Map configurations = new HashMap<>();

public void addConfig(String name, Config config) {

configurations.put(name, config);

}

public Optional getConfig(String name, Class type) {

Config config = configurations.get(name);

return type.isInstance(config) ? Optional.of(type.cast(config)) : Optional.empty();

}

public void printAllConfigs() {

configurations.forEach((name, config) -> {

switch (config) {

case DatabaseConfig db ->

System.out.println(数据库配置: + db.url());

case ApiConfig api ->

System.out.println(API配置: + api.baseUrl());

case CacheConfig cache ->

System.out.println(缓存配置: + cache.redisHost());

}

});

}

}

```

## 最佳实践与性能考虑

### 记录类最佳实践

1. 适用场景:数据传输对象、值对象、不可变数据容器

2. 避免滥用:不适合需要复杂继承或可变状态的场景

3. 序列化:记录类天然支持序列化,但要注意字段兼容性

### 密封类最佳实践

1. API设计:使用密封类定义稳定的API接口

2. 模式匹配:充分利用switch表达式进行类型安全的模式匹配

3. 扩展性:合理使用non-sealed为未来扩展留出空间

### 性能优势

- 记录类减少了样板代码,提升开发效率

- 密封类在模式匹配时提供更好的性能优化机会

- 两者结合使用可以创建更安全、更高效的类型系统

通过合理运用记录类和密封类,开发者可以构建出更加类型安全、易于维护的Java应用程序,同时享受现代Java语言特性带来的开发便利。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐