Java17新特性解析记录类与密封类的实战应用指南
# 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语言特性带来的开发便利。
更多推荐



所有评论(0)