Java,一直被开发者戏称为“啰嗦”,但从 JDK 12 到 JDK 17,这门语言发生了显著变化。多个语法层面的增强让 Java 更加简洁、表达力更强,也更接近现代语言的风格。本文将带你梳理这六个版本中 Java 的关键语法演进。
👀语法新特性一览
🌟 1. switch 表达式:不再“陷阱重重”
🚧 痛点
传统 switch 不支持返回值,且 break 的遗漏常导致 bug。
✅ 新特性(JEP 325/354/361)
switch可作为表达式返回值- 引入箭头语法(
->) - 支持多标签匹配
 - 使用 
yield显式返回值 
🌰 示例
对 HTTP 状态码进行分类处理,例如:构建统一响应消息或记录错误日志。
String result = switch (statusCode) {
    case 200 -> "OK";
    case 404 -> "Not Found";
    case 500 -> {
        logError();
        yield "Server Error";
    }
    default -> "Unknown";
};
✅ 优势:简洁、安全、不易出错,便于表达逻辑分支。
看机会
技术大厂→跳板→跳板,前端-后端-测试,待遇和稳定性都还不错,感兴趣可以试试~
🧾 2. 文本块(Text Blocks):三引号带来的优雅字符串
🚧 痛点
传统多行字符串使用 \n 和拼接,代码难读难维护。
✅ 新特性(JEP 355/368/378)
- 多行字符串使用 
"""定义 - 自动处理缩进和换行
 - 支持行连接符 ``
 
🌰 示例
构建 SQL 查询语句、HTML 页面模板、JSON 配置片段。
示例1-sql查询
String query = """
    SELECT id, name, email
    FROM users
    WHERE status = 'ACTIVE'
    ORDER BY created_at DESC
    """;
示例2-html模板
String html = """
    <html>
        <body>
            <h1>Welcome, %s!</h1>
        </body>
    </html>
    """.formatted(user.getName());
✅ 优势:更易编写 JSON、SQL、HTML 等嵌入式文本内容。
🔍 3. instanceof 模式匹配:更聪明的类型判断
🚧 痛点
类型判断后必须显式强转,重复又冗余。
✅ 新特性(JEP 305,JDK 16):
- 支持 
instanceof时绑定变量 
🌰 示例
处理请求参数、事件派发、策略模式中类型判断。
public void process(Object input) {
    if (input instanceof String s) {
        handleText(s);
    } else if (input instanceof Integer i) {
        handleNumber(i);
    } else {
        throw new IllegalArgumentException("Unsupported input type");
    }
}
✅ 优势:去除显式强转,更易读、易写、安全。
🧱 4. record 类:轻松定义数据载体
🚧 痛点
定义一个 POJO 需要写大量样板代码(构造器、getter、equals 等)。
✅ 新特性(JEP 384,JDK 16)
- 一行代码定义不可变数据类
 - 自动生成构造器、访问器、
equals、hashCode、toString 
🌰 示例
用于接口响应对象、查询结果封装、消息体定义
示例1-接口响应
public record ApiResponse<T>(int code, String message, T data) {}
ApiResponse<User> response = new ApiResponse<>(200, "OK", user);
示例2-封装查询结果
public record UserSummary(String name, int postCount) {}
List<UserSummary> summaries = userRepository.getSummaries();
✅ 优势:专为数据建模而生,简洁且不易出错。
🔐 5. 密封类(Sealed Classes):限制继承范围
🚧 痛点
接口或抽象类可以被任意扩展,无法控制子类范围。
✅ 新特性(JEP 360,JDK 17)
- 使用 
sealed修饰类/接口 - 显式声明允许继承的子类(使用 
permits) 
🌰 示例
用于建模流程状态、支付状态、登录结果、事件分发等,确保所有子类都是受控的。
支付状态
public sealed interface PaymentResult permits Success, Failure {}
public final class Success implements PaymentResult {
    String transactionId;
    // ...
}
public final class Failure implements PaymentResult {
    String reason;
    // ...
}
处理支付结果:
void handle(PaymentResult result) {
    if (result instanceof Success s) {
        log("Success: " + s.transactionId());
    } else if (result instanceof Failure f) {
        log("Failure: " + f.reason());
    }
}
✅ 优势:提供受控扩展,便于在模式匹配和状态建模中使用。
📶web应用中的实际使用
我们假设web应用有以下功能:用户提交订单后,系统处理订单并返回处理结果(成功、库存不足、支付失败等状态)。
📦 1. 使用 record 定义响应对象与DTO
📌 文件:OrderRequest.java
public record OrderRequest(Long userId, List<Long> productIds, String paymentType) {}
📌 文件:OrderResponse.java
public record OrderResponse(String orderNo, String message, int code) {}
✅ 用途:
- 在 Controller 层接收请求/返回响应;
 - 省略 getter/setter/构造器;
 - 天然不可变,适合并发和函数式风格。
 
🧠 2. 使用 sealed + instanceof 进行订单结果建模和处理
📌 文件:OrderResult.java
public sealed interface OrderResult permits OrderSuccess, OrderFailure {}
public final class OrderSuccess implements OrderResult {
    public final String orderNo;
    public OrderSuccess(String orderNo) {
        this.orderNo = orderNo;
    }
}
public final class OrderFailure implements OrderResult {
    public final String reason;
    public OrderFailure(String reason) {
        this.reason = reason;
    }
}
📌 在 Service 中处理结果:
public OrderResponse handleResult(OrderResult result) {
    if (result instanceof OrderSuccess success) {
        return new OrderResponse(success.orderNo, "下单成功", 200);
    } else if (result instanceof OrderFailure failure) {
        return new OrderResponse(null, failure.reason, 500);
    }
    throw new IllegalStateException("未知结果类型");
}
✅ 优点:
- 明确约束返回类型;
 - 避免非法实现或扩展;
 - 结合 
instanceof 模式匹配,写法简洁明了。 
🔁 3. 使用 switch 表达式处理支付类型
📌 文件:PaymentType.java(枚举)
public enum PaymentType {
    CREDIT_CARD, WECHAT, ALIPAY
}
📌 在 Service 层选择支付服务:
public PaymentService getPaymentService(PaymentType type) {
    return switch (type) {
        case CREDIT_CARD -> creditCardService;
        case WECHAT -> wechatPayService;
        case ALIPAY -> aliPayService;
    };
}
✅ 优点:
- 替代 if-else,代码更整洁;
 - 编译器检查是否遗漏分支。
 
🧾 4. 使用文本块生成 SQL 或消息模板
📌 在 Repository 中写动态 SQL:
String sql = """
    SELECT * FROM orders
    WHERE user_id = ?
    AND created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
    ORDER BY created_at DESC
    """;
📌 发送邮件或通知模板:
String content = """
    亲爱的用户,您的订单已成功创建:
    订单编号:%s
    总金额:%.2f 元
    感谢您的购买!
    """.formatted(orderNo, totalAmount);
✅ 优点:
- 无需拼接;
 - 保持结构清晰,适合业务模板开发。
 
🌐 5. Controller 层综合调用示例
@RestController
@RequestMapping("/orders")
public class OrderController {
    @PostMapping
    public ResponseEntity<OrderResponse> placeOrder(@RequestBody OrderRequest request) {
        OrderResult result = orderService.createOrder(request);
        OrderResponse response = orderService.handleResult(result);
        return ResponseEntity.status(response.code()).body(response);
    }
}
✅ 综合收益总结
| 特性 | 实际作用 | 模块 | 
|---|---|---|
record | 快速构建不可变 DTO 与响应体 | Controller/DTO | 
sealed | 精确限定子类,建模业务状态 | Service/Domain | 
instanceof 模式匹配 | 简洁判断不同业务返回类型 | Service | 
switch 表达式 | 优雅地分发策略/状态处理 | Service | 
| 文本块 | 结构化模板与 SQL 管理更清晰 | Repository/通知模板 | 
🧩 总结一览表
新特性总结:
| 特性 | JEP | Java版本 | 优势 | 
|---|---|---|---|
switch 表达式 | 325/354/361 | 12-14 | 表达式化、安全简洁 | 
| 文本块 | 355/368/378 | 13-15 | 编写多行字符串更自然 | 
instanceof 模式匹配 | 305 | 16 | 去除强转,增强可读性 | 
record 类 | 384 | 16 | 快速定义不可变数据类 | 
| 密封类 | 360 | 17 | 限制继承,提高建模安全性 | 
最佳使用场景总结:
| 特性 | 实践推荐场景 | 说明 | 
|---|---|---|
switch 表达式 | 状态判断、分支处理、枚举映射 | 替代复杂 if-else | 
| 文本块 | SQL/HTML/JSON模板、配置文件构造 | 可读性强 | 
instanceof 模式匹配 | 类型分发、策略切换、事件处理 | 精简类型判断 | 
record 类 | 响应对象、DTO、只读配置结构体 | 最适合不可变数据 | 
| 密封类 | 状态机建模、业务结果分类、事件系统 | 编译时安全的继承控制 | 
📌 写在最后
从 JDK12 到 JDK17,Java 逐步摆脱了“啰嗦语言”的帽子,走上了现代化转型之路。这些语法特性使得日常开发更高效、代码更简洁,也更易于维护。
未来的 Java 不再只是“企业级”稳重代名词,它正在变得更轻盈、更聪明——值得每一位开发者重新审视与拥抱。
——转载自:橙序员小站
