Java 17+ 新特性实战

Java 17 是 LTS 版本,带来了 record、sealed class、switch 模式匹配等一大批改变写法的特性。本文用实战例子讲清这些新特性怎么用、什么时候用。

Java 新特性配图:蓝色渐变背景上盾牌密封层级与拼图块匹配,扁平科技插画
Java 17+:record、sealed 与模式匹配改变 Java 的写法

一、record:数据类一行搞定

以前写一个纯数据类要写一堆 getter、setter、equals、hashCode、toString。record 一行搞定:

// 以前:要写 100 行的 POJO
public class User {
    private final Long id;
    private final String name;
    private final String email;
    // 构造器、getter、equals、hashCode、toString 全部手写
}

// 现在:一行 record
public record User(Long id, String name, String email) {}

// 自动生成:构造器、字段访问器、equals、hashCode、toString
User u = new User(1L, "小明", "xm@example.com");
System.out.println(u.name());  // 访问器方法(不是 getName())
System.out.println(u);
// User[id=1, name=小明, email=xm@example.com]
注意:record 是 final 的,不能继承其他类。字段是 final 的。适合 DTO、值对象、数据载体。不适合需要继承或可变状态的实体。

二、sealed class:限制继承层级

以前 Java 的类要么可以随便被继承(默认),要么不能被继承(final)。sealed 在中间:明确列出允许哪些子类继承。

// 密封类:只允许 Circle、Rectangle、Triangle 继承
public sealed interface Shape
    permits Circle, Rectangle, Triangle {}

public record Circle(double radius) implements Shape {}
public record Rectangle(double width, double height) implements Shape {}
public record Triangle(double base, double height) implements Shape {}

// 不允许其他类继承 Shape,编译器会报错

sealed 配合 switch 模式匹配,编译器可以帮你检查是否覆盖了所有子类。

三、switch 模式匹配

以前的 switch 只能匹配常量。现在 switch 可以匹配类型、解构 record、加条件判断。

// 以前:instanceof 加类型强转,啰嗦
public static double area(Shape shape) {
    if (shape instanceof Circle c) {
        return Math.PI * c.radius() * c.radius();
    } else if (shape instanceof Rectangle r) {
        return r.width() * r.height();
    } else if (shape instanceof Triangle t) {
        return 0.5 * t.base() * t.height();
    }
    throw new IllegalArgumentException();
}

// 现在:switch 模式匹配,简洁优雅
public static double area(Shape shape) {
    return switch (shape) {
        case Circle c -> Math.PI * c.radius() * c.radius();
        case Rectangle r -> r.width() * r.height();
        case Triangle t -> 0.5 * t.base() * t.height();
        // sealed 保证穷尽,不需要 default
    };
}

四、模式匹配的进阶用法

// 带条件的模式匹配
public static String classify(Number num) {
    return switch (num) {
        case Integer i when i > 0 -> "正整数";
        case Integer i when i < 0 -> "负整数";
        case Integer i -> "零";
        case Double d when d > 0 -> "正小数";
        case null -> "空值";
        default -> "其他数字";
    };
}

// record 解构
record Point(int x, int y) {}
record Line(Point start, Point end) {}

public static void printLine(Line line) {
    if (line instanceof Line(Point(var x1, var y1), Point(var x2, var y2))) {
        System.out.printf("从(%d,%d)到(%d,%d)%n", x1, y1, x2, y2);
    }
}

五、其他实用新特性

// Text Blocks(文本块):多行字符串不用拼接
String json = """
    {
        "name": "小明",
        "age": 25
    }
    """;

// var 类型推断(局部变量)
var list = new ArrayList<String>();
var map = new HashMap<String, Object>();

// instanceof 模式匹配
if (obj instanceof String s && s.length() > 5) {
    System.out.println(s.toUpperCase());
}

六、什么时候用这些新特性

特性使用场景
recordDTO、值对象、数据载体
sealed领域模型有明确子类层级时
switch 模式匹配多类型分支逻辑替代 if-else 链
Text BlocksJSON、SQL、HTML 多行字符串
var局部变量类型明显时(如 new HashMap<String, Object>())

七、总结

Java 17+ 的新特性不是锦上添花,而是让 Java 代码更简洁、更安全。record 消灭了 POJO 样板代码,sealed 让领域模型层级更可控,switch 模式匹配替代了啰嗦的 if-else 链。新项目直接用 Java 17+,老项目逐步迁移这些特性。