
Java 25 密封类增强更安全、更灵活的类型体系别叫我大神叫我 Alex 就好Java 25 对密封类Sealed Classes功能进行了显著增强为开发者提供了更安全、更灵活的类型体系。本文将详细介绍 Java 25 密封类的新特性包括扩展限制、模式匹配集成、嵌套密封类等并通过实际例子展示如何使用这些特性提升代码质量。1. 密封类简介密封类是 Java 15 引入的特性它允许开发者限制类的继承关系确保只有指定的类可以继承该类。Java 25 进一步增强了这一功能使其更加灵活和强大继承限制限制哪些类可以继承密封类模式匹配与 switch 表达式和 instanceof 操作符集成嵌套密封类支持在密封类内部定义密封子类接口密封支持密封接口穷尽性检查编译器对密封类型的 switch 语句进行穷尽性检查2. 基本用法2.1 定义密封类// 基本密封类 public sealed class Shape permits Circle, Rectangle, Triangle { // 共同方法 public abstract double area(); } // 允许的子类 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; } } 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; } } public final 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; } }2.2 密封接口// 密封接口 public sealed interface Operation permits Add, Subtract, Multiply, Divide { double apply(double a, double b); } // 允许的实现类 public final class Add implements Operation { Override public double apply(double a, double b) { return a b; } } public final class Subtract implements Operation { Override public double apply(double a, double b) { return a - b; } } public final class Multiply implements Operation { Override public double apply(double a, double b) { return a * b; } } public final class Divide implements Operation { Override public double apply(double a, double b) { if (b 0) { throw new ArithmeticException(Division by zero); } return a / b; } }3. 高级特性3.1 非最终子类密封类的子类可以是非最终的只要它们也是密封的或非密封的// 密封类 public sealed class Vehicle permits Car, Truck, Motorcycle { // 共同方法 } // 密封子类 public sealed class Car extends Vehicle permits Sedan, SUV, SportsCar { // 汽车特有方法 } // 最终子类 public final class Sedan extends Car { // 实现 } public final class SUV extends Car { // 实现 } public final class SportsCar extends Car { // 实现 } // 非密封子类 public non-sealed class Truck extends Vehicle { // 实现 } // 最终子类 public final class Motorcycle extends Vehicle { // 实现 } // 可以继承非密封的 Truck public class PickupTruck extends Truck { // 实现 }3.2 嵌套密封类Java 25 支持在密封类内部定义密封子类// 嵌套密封类 public sealed class Expression { // 嵌套密封子类 public static sealed class Constant extends Expression permits IntConstant, DoubleConstant { // 实现 } public static final class IntConstant extends Constant { private final int value; public IntConstant(int value) { this.value value; } public int getValue() { return value; } } public static final class DoubleConstant extends Constant { private final double value; public DoubleConstant(double value) { this.value value; } public double getValue() { return value; } } public static final class Addition extends Expression { private final Expression left; private final Expression right; public Addition(Expression left, Expression right) { this.left left; this.right right; } public Expression getLeft() { return left; } public Expression getRight() { return right; } } }3.3 模式匹配集成// 模式匹配与密封类 public double evaluate(Expression expr) { return switch (expr) { case Expression.Constant c - { if (c instanceof Expression.IntConstant ic) { return ic.getValue(); } else if (c instanceof Expression.DoubleConstant dc) { return dc.getValue(); } else { throw new IllegalArgumentException(Unknown constant type); } } case Expression.Addition a - evaluate(a.getLeft()) evaluate(a.getRight()); // 编译器会检查穷尽性 }; } // 更简洁的模式匹配 public double evaluate(Expression expr) { return switch (expr) { case Expression.IntConstant(int value) - value; case Expression.DoubleConstant(double value) - value; case Expression.Addition(Expression left, Expression right) - evaluate(left) evaluate(right); // 编译器会检查穷尽性 }; }4. 实际应用场景4.1 状态管理// 状态管理 public sealed interface OrderStatus permits Pending, Processing, Shipped, Delivered, Cancelled { String getStatus(); } public record Pending() implements OrderStatus { Override public String getStatus() { return PENDING; } } public record Processing() implements OrderStatus { Override public String getStatus() { return PROCESSING; } } public record Shipped(String trackingNumber) implements OrderStatus { Override public String getStatus() { return SHIPPED; } } public record Delivered(LocalDateTime deliveryTime) implements OrderStatus { Override public String getStatus() { return DELIVERED; } } public record Cancelled(String reason) implements OrderStatus { Override public String getStatus() { return CANCELLED; } } // 状态处理 public String processOrderStatus(OrderStatus status) { return switch (status) { case Pending() - Order is pending payment; case Processing() - Order is being processed; case Shipped(String trackingNumber) - Order has been shipped. Tracking: trackingNumber; case Delivered(LocalDateTime time) - Order delivered on time.format(DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm)); case Cancelled(String reason) - Order cancelled: reason; }; }4.2 命令模式// 命令模式 public sealed interface Command permits CreateUser, UpdateUser, DeleteUser, GetUser { Object execute(); } public record CreateUser(String name, String email, UserRepository repository) implements Command { Override public Object execute() { User user new User(name, email); repository.save(user); return user; } } public record UpdateUser(long id, String name, String email, UserRepository repository) implements Command { Override public Object execute() { User user repository.findById(id) .orElseThrow(() - new UserNotFoundException(id)); user.setName(name); user.setEmail(email); repository.save(user); return user; } } public record DeleteUser(long id, UserRepository repository) implements Command { Override public Object execute() { repository.deleteById(id); return User deleted successfully; } } public record GetUser(long id, UserRepository repository) implements Command { Override public Object execute() { return repository.findById(id) .orElseThrow(() - new UserNotFoundException(id)); } } // 命令执行器 public class CommandExecutor { public Object execute(Command command) { return command.execute(); } }4.3 表达式求值// 表达式求值 public sealed interface Expr permits Constant, Variable, Add, Subtract, Multiply, Divide { double evaluate(MapString, Double variables); } public record Constant(double value) implements Expr { Override public double evaluate(MapString, Double variables) { return value; } } public record Variable(String name) implements Expr { Override public double evaluate(MapString, Double variables) { Double value variables.get(name); if (value null) { throw new IllegalArgumentException(Variable not found: name); } return value; } } public record Add(Expr left, Expr right) implements Expr { Override public double evaluate(MapString, Double variables) { return left.evaluate(variables) right.evaluate(variables); } } public record Subtract(Expr left, Expr right) implements Expr { Override public double evaluate(MapString, Double variables) { return left.evaluate(variables) - right.evaluate(variables); } } public record Multiply(Expr left, Expr right) implements Expr { Override public double evaluate(MapString, Double variables) { return left.evaluate(variables) * right.evaluate(variables); } } public record Divide(Expr left, Expr right) implements Expr { Override public double evaluate(MapString, Double variables) { double rightValue right.evaluate(variables); if (rightValue 0) { throw new ArithmeticException(Division by zero); } return left.evaluate(variables) / rightValue; } }5. 性能优化5.1 编译时优化Java 25 对密封类进行了编译时优化类型检查编译器对密封类型的 switch 语句进行穷尽性检查模式匹配生成更高效的模式匹配代码继承关系优化密封类的继承关系检查内存使用减少密封类的内存开销5.2 代码优化// 优化前使用接口和 instanceof 检查 public String processShape(Shape shape) { if (shape instanceof Circle) { Circle circle (Circle) shape; return Circle with radius circle.getRadius(); } else if (shape instanceof Rectangle) { Rectangle rectangle (Rectangle) shape; return Rectangle with width rectangle.getWidth() and height rectangle.getHeight(); } else if (shape instanceof Triangle) { Triangle triangle (Triangle) shape; return Triangle with base triangle.getBase() and height triangle.getHeight(); } else { throw new IllegalArgumentException(Unknown shape type); } } // 优化后使用 switch 表达式和模式匹配 public String processShape(Shape shape) { return switch (shape) { case Circle(double radius) - Circle with radius radius; case Rectangle(double width, double height) - Rectangle with width width and height height; case Triangle(double base, double height) - Triangle with base base and height height; // 编译器会检查穷尽性 }; }6. 最佳实践6.1 代码风格// 推荐使用记录类型作为密封子类 public sealed interface Status permits Active, Inactive, Error { } public record Active(String message) implements Status { } public record Inactive(String reason) implements Status { } public record Error(String error) implements Status { } // 推荐使用密封类进行状态管理 public sealed class State permits Ready, Running, Stopped, Failed { // 共同状态 } // 推荐与模式匹配结合使用 public String getStateDescription(State state) { return switch (state) { case Ready() - System is ready; case Running() - System is running; case Stopped(String reason) - System is stopped: reason; case Failed(String error) - System failed: error; }; }6.2 设计原则明确的继承关系使用密封类明确指定哪些类可以继承穷尽性检查利用编译器的穷尽性检查确保所有情况都被处理模式匹配与模式匹配结合使用简化代码记录类型使用记录类型作为密封子类减少样板代码层次结构合理设计密封类的层次结构6.3 错误处理// 错误处理 public sealed interface ResultT permits Success, Failure { T getOrElse(T defaultValue); U ResultU map(FunctionT, U mapper); } public record SuccessT(T value) implements ResultT { Override public T getOrElse(T defaultValue) { return value; } Override public U ResultU map(FunctionT, U mapper) { return new Success(mapper.apply(value)); } } public record FailureT(Exception error) implements ResultT { Override public T getOrElse(T defaultValue) { return defaultValue; } Override public U ResultU map(FunctionT, U mapper) { return new Failure(error); } } // 使用 public ResultUser getUser(long id) { try { User user userRepository.findById(id) .orElseThrow(() - new UserNotFoundException(id)); return new Success(user); } catch (Exception e) { return new Failure(e); } } // 处理结果 ResultUser result getUser(1L); String name result.map(User::getName).getOrElse(Unknown);7. 实际案例分析7.1 电商系统订单状态某电商系统使用密封类管理订单状态// 订单状态 public sealed interface OrderState permits Created, Paid, Shipped, Delivered, Cancelled { OrderState next(); OrderState cancel(String reason); } public record Created() implements OrderState { Override public OrderState next() { return new Paid(); } Override public OrderState cancel(String reason) { return new Cancelled(reason); } } public record Paid() implements OrderState { Override public OrderState next() { return new Shipped(tracking- UUID.randomUUID()); } Override public OrderState cancel(String reason) { return new Cancelled(reason); } } // 其他状态实现... // 订单状态流转 public class Order { private OrderState state; public Order() { this.state new Created(); } public void process() { this.state state.next(); } public void cancel(String reason) { this.state state.cancel(reason); } public String getStatus() { return switch (state) { case Created() - Created; case Paid() - Paid; case Shipped(String tracking) - Shipped ( tracking ); case Delivered() - Delivered; case Cancelled(String reason) - Cancelled: reason; }; } }7.2 金融系统交易类型某金融系统使用密封类处理不同类型的交易// 交易类型 public sealed interface Transaction permits Deposit, Withdrawal, Transfer, Payment { double execute(Account account); } public record Deposit(double amount) implements Transaction { Override public double execute(Account account) { account.deposit(amount); return account.getBalance(); } } public record Withdrawal(double amount) implements Transaction { Override public double execute(Account account) { if (account.getBalance() amount) { throw new InsufficientFundsException(); } account.withdraw(amount); return account.getBalance(); } } // 其他交易类型实现... // 交易处理 public class TransactionProcessor { public double process(Account account, Transaction transaction) { return transaction.execute(account); } }8. 未来发展8.1 语言级支持未来的 Java 版本可能会进一步增强密封类更灵活的继承限制支持更复杂的继承限制规则接口默认方法密封接口的默认方法增强注解支持为密封类添加更多注解支持与其他特性集成与模式匹配、记录类型等特性的更深层次集成8.2 工具支持IDE 支持更好的密封类语法高亮和代码提示静态分析更强大的密封类静态分析工具代码生成基于密封类的代码生成工具文档生成自动生成密封类层次结构文档9. 迁移策略9.1 逐步迁移识别适合的场景选择适合使用密封类的场景小范围试点在小范围内试点使用密封类逐步推广将成功经验推广到更多场景代码审查确保密封类的使用符合最佳实践9.2 混合使用在迁移过程中可以混合使用密封类和传统类// 混合使用 public class LegacyClass { // 传统类 } public sealed class ModernClass permits SubClass1, SubClass2 { // 密封类 } public final class SubClass1 extends ModernClass { // 密封子类 } public final class SubClass2 extends ModernClass { // 密封子类 }10. 总结Java 25 的密封类增强为开发者提供了一种更安全、更灵活的类型体系。通过限制继承关系、与模式匹配集成、支持嵌套密封类等特性密封类使代码更加清晰、安全、易维护。作为开发者我们应该积极探索密封类的应用场景利用它来简化代码提高开发效率。无论是状态管理、命令模式还是表达式求值密封类都能让我们的代码更加优雅。密封类是 Java 语言的重要进化它将改变我们设计类型体系的方式。让我们拥抱这一技术趋势写出更优雅的代码这其实可以更优雅一点在使用 Java 25 密封类时我们可以通过以下方式让代码更优雅使用记录类型将密封子类定义为记录类型减少样板代码结合模式匹配与 switch 表达式和模式匹配结合使用合理设计层次设计清晰的密封类层次结构利用穷尽性检查让编译器帮助我们检查所有可能的情况保持简洁每个密封类和子类都应该保持简洁明了Alex专注于 Java 技术分享致力于帮助开发者构建更优雅的应用系统