Java 17 密封类(Sealed Classes)增强案例
密封类是Java 17正式引入的一个重要特性,它允许你控制哪些类可以继承或实现某个类/接口,让我通过几个实际案例来展示它的强大功能。

基础案例:形状计算系统
// 定义密封接口
public sealed interface Shape permits Circle, Rectangle, Triangle {
double area();
double perimeter();
}
// 圆形实现
public final class Circle implements 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 double getRadius() {
return radius;
}
}
// 矩形实现
public final class Rectangle implements 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 double getWidth() {
return width;
}
public double getHeight() {
return height;
}
}
// 三角形实现
public final class Triangle implements Shape {
private final double side1;
private final double side2;
private final double side3;
public Triangle(double side1, double side2, double side3) {
this.side1 = side1;
this.side2 = side2;
this.side3 = side3;
}
@Override
public double area() {
// 使用海伦公式
double s = (side1 + side2 + side3) / 2;
return Math.sqrt(s * (s - side1) * (s - side2) * (s - side3));
}
@Override
public double perimeter() {
return side1 + side2 + side3;
}
}
与模式匹配结合使用
// Java 17+ 模式匹配与密封类的完美结合
public class ShapeProcessor {
// 使用模式匹配处理不同形状
public static String describeShape(Shape shape) {
return switch (shape) {
case Circle c -> String.format("圆形,半径: %.2f,面积: %.2f",
c.getRadius(), c.area());
case Rectangle r -> String.format("矩形,宽: %.2f,高: %.2f,面积: %.2f",
r.getWidth(), r.getHeight(), r.area());
case Triangle t -> String.format("三角形,三边: %.2f, %.2f, %.2f,面积: %.2f",
t.getSide1(), t.getSide2(), t.getSide3(),
t.area());
};
}
// 验证形状是否合法
public static boolean isValidShape(Shape shape) {
return switch (shape) {
case Circle c -> c.getRadius() > 0;
case Rectangle r -> r.getWidth() > 0 && r.getHeight() > 0;
case Triangle t -> validTriangle(t.getSide1(), t.getSide2(), t.getSide3());
};
}
private static boolean validTriangle(double a, double b, double c) {
return a > 0 && b > 0 && c > 0 &&
(a + b > c) && (a + c > b) && (b + c > a);
}
}
简化中间类继承
// 使用non-sealed允许部分子类开放继承
public sealed class Vehicle permits Car, Truck, Motorcycle {
private final String brand;
private final String model;
public Vehicle(String brand, String model) {
this.brand = brand;
this.model = model;
}
public String getBrand() {
return brand;
}
public String getModel() {
return model;
}
public abstract double getMaxSpeed();
}
// 使用non-sealed允许进一步继承
public non-sealed class Car extends Vehicle {
private final int passengerCapacity;
public Car(String brand, String model, int passengerCapacity) {
super(brand, model);
this.passengerCapacity = passengerCapacity;
}
@Override
public double getMaxSpeed() {
return 250.0;
}
public int getPassengerCapacity() {
return passengerCapacity;
}
}
// 使用final表示最终类
public final class Truck extends Vehicle {
private final double loadCapacity;
public Truck(String brand, String model, double loadCapacity) {
super(brand, model);
this.loadCapacity = loadCapacity;
}
@Override
public double getMaxSpeed() {
return 120.0;
}
public double getLoadCapacity() {
return loadCapacity;
}
}
// 可以继续继承Car,因为它是non-sealed
public class SUV extends Car {
private final boolean fourWheelDrive;
public SUV(String brand, String model, int passengerCapacity, boolean fourWheelDrive) {
super(brand, model, passengerCapacity);
this.fourWheelDrive = fourWheelDrive;
}
@Override
public double getMaxSpeed() {
return 200.0;
}
public boolean isFourWheelDrive() {
return fourWheelDrive;
}
}
实际业务场景:支付系统
// 支付系统示例
public sealed interface PaymentMethod permits CreditCard, DebitCard, CryptoWallet {
String getProvider();
double processPayment(double amount);
}
// 信用卡实现
public final class CreditCard implements PaymentMethod {
private final String cardNumber;
private final String expiryDate;
public CreditCard(String cardNumber, String expiryDate) {
this.cardNumber = cardNumber;
this.expiryDate = expiryDate;
}
@Override
public String getProvider() {
return "Visa/MasterCard";
}
@Override
public double processPayment(double amount) {
// 信用卡支付逻辑
double fee = amount * 0.02; // 2%手续费
return amount + fee;
}
public String getCardNumber() {
return cardNumber;
}
}
// 借记卡实现
public final class DebitCard implements PaymentMethod {
private final String bankName;
private final String accountNumber;
public DebitCard(String bankName, String accountNumber) {
this.bankName = bankName;
this.accountNumber = accountNumber;
}
@Override
public String getProvider() {
return bankName;
}
@Override
public double processPayment(double amount) {
// 借记卡支付逻辑
return amount; // 无额外手续费
}
public String getBankName() {
return bankName;
}
}
// 加密货币钱包
public final class CryptoWallet implements PaymentMethod {
private final String walletAddress;
private final String currency;
public CryptoWallet(String walletAddress, String currency) {
this.walletAddress = walletAddress;
this.currency = currency;
}
@Override
public String getProvider() {
return "Crypto";
}
@Override
public double processPayment(double amount) {
// 加密货币支付逻辑
double fee = amount * 0.001; // 0.1%手续费
return amount + fee;
}
public String getWalletAddress() {
return walletAddress;
}
}
// 支付处理器
public class PaymentProcessor {
public static String processPayment(PaymentMethod method, double amount) {
return switch (method) {
case CreditCard cc -> String.format(
"信用卡支付: 金额=%.2f, 手续费=%.2f, 总计=%.2f, 卡号最后4位=%s",
amount, method.processPayment(amount) - amount,
method.processPayment(amount),
cc.getCardNumber().substring(cc.getCardNumber().length() - 4));
case DebitCard dc -> String.format(
"借记卡支付: 金额=%.2f, 手续费=0.00, 总计=%.2f, 银行=%s",
amount, method.processPayment(amount), dc.getBankName());
case CryptoWallet cw -> String.format(
"加密货币支付: 金额=%.2f, 手续费=%.2f, 总计=%.2f, 币种=%s",
amount, method.processPayment(amount) - amount,
method.processPayment(amount), cw.getCurrency());
};
}
}
测试代码
public class SealedClassDemo {
public static void main(String[] args) {
// 测试形状系统
System.out.println("=== 形状系统测试 ===");
Shape circle = new Circle(5);
Shape rectangle = new Rectangle(4, 6);
Shape triangle = new Triangle(3, 4, 5);
System.out.println(ShapeProcessor.describeShape(circle));
System.out.println(ShapeProcessor.describeShape(rectangle));
System.out.println(ShapeProcessor.describeShape(triangle));
// 测试支付系统
System.out.println("\n=== 支付系统测试 ===");
PaymentMethod creditCard = new CreditCard("1234-5678-9012-3456", "12/25");
PaymentMethod debitCard = new DebitCard("中国工商银行", "6222021234567890");
PaymentMethod cryptoWallet = new CryptoWallet("0x1234...", "ETH");
System.out.println(PaymentProcessor.processPayment(creditCard, 1000));
System.out.println(PaymentProcessor.processPayment(debitCard, 500));
System.out.println(PaymentProcessor.processPayment(cryptoWallet, 800));
}
}
输出结果
=== 形状系统测试 ===
圆形,半径: 5.00,面积: 78.54
矩形,宽: 4.00,高: 6.00,面积: 24.00
三角形,三边: 3.00, 4.00, 5.00,面积: 6.00
=== 支付系统测试 ===
信用卡支付: 金额=1000.00, 手续费=20.00, 总计=1020.00, 卡号最后4位=3456
借记卡支付: 金额=500.00, 手续费=0.00, 总计=500.00, 银行=中国工商银行
加密货币支付: 金额=800.00, 手续费=0.80, 总计=800.80, 币种=ETH
密封类的关键优势
- 代码安全性:明确限制继承关系,防止意外扩展
- 模式匹配完备性:编译器知道所有子类型,switch表达式不需要default分支
- API设计清晰:明确表达类层次结构的完整性和封闭性
- 更好的类型安全性:配合模式匹配,减少类型转换错误
- 可维护性:代码结构更清晰,易于理解和维护
密封类是Java 17中一个非常实用的特性,特别适合用于领域模型设计、状态机实现和API设计等场景。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播