⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 juejin.cn/post/7531524096649379892 「橙序员小站」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言都将得到认真回复。甚至不知道如何读源码也可以请教噢。
  4. 新的源码解析文章实时收到通知。每周更新一篇左右。
  5. 认真的源码交流微信群。

Java,一直被开发者戏称为”啰嗦”,但从 JDK 12 到 JDK 17,这门语言发生了显著变化。多个语法层面的增强让 Java 更加简洁、表达力更强,也更接近现代语言的风格。本文将带你梳理这六个版本中 Java 的关键语法演进。

语法新特性一览

1. switch 表达式:不再”陷阱重重”

痛点

传统 switch 不支持返回值,且 break 的遗漏常导致 bug。

新特性(JEP 325/354/361)

  • switch 可作为表达式返回值
  • 引入箭头语法(->)
  • 支持多标签匹配
  • 使用 yield 显式返回值

示例

对 HTTP 状态码进行分类处理,例如:构建统一响应消息或记录错误日志。

String result = switch (statusCode) {  
case200 -> "OK";
case404 -> "Not Found";
case500 -> {
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 时绑定变量

示例

处理请求参数、事件派发、策略模式中类型判断。

publicvoidprocess(Object input){  
if (input instanceof String s) {
handleText(s);
} elseif (input instanceof Integer i) {
handleNumber(i);
} else {
thrownew 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 interfacePaymentResultpermitsSuccess, Failure{}  

publicfinalclassSuccessimplementsPaymentResult{
String transactionId;
// ...
}

publicfinalclassFailureimplementsPaymentResult{
String reason;
// ...
}

处理支付结果:

voidhandle(PaymentResult result){  
if (result instanceof Success s) {
log("Success: " + s.transactionId());
} elseif (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 interfaceOrderResultpermitsOrderSuccess, OrderFailure{}  

publicfinalclassOrderSuccessimplementsOrderResult{
publicfinal String orderNo;
publicOrderSuccess(String orderNo){
this.orderNo = orderNo;
}
}

publicfinalclassOrderFailureimplementsOrderResult{
publicfinal String reason;
publicOrderFailure(String reason){
this.reason = reason;
}
}

在 Service 中处理结果:

public OrderResponse handleResult(OrderResult result){  
if (result instanceof OrderSuccess success) {
returnnew OrderResponse(success.orderNo, "下单成功", 200);
} elseif (result instanceof OrderFailure failure) {
returnnew OrderResponse(null, failure.reason, 500);
}
thrownew IllegalStateException("未知结果类型");
}

优点:

  • 明确约束返回类型;
  • 避免非法实现或扩展;
  • 结合 instanceof 模式匹配,写法简洁明了。

3. 使用 switch 表达式处理支付类型

文件:PaymentType.java(枚举)

publicenum PaymentType {  
CREDIT_CARD, WECHAT, ALIPAY
}

在 Service 层选择支付服务:

public PaymentService getPaymentService(PaymentType type){  
returnswitch (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")
publicclassOrderController{

@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、只读配置结构体 最适合不可变数据
密封类 状态机建模、业务结果分类、事件系统 编译时安全的继承控制

写在最后

从 JDK 12 到 JDK 17,Java 逐步摆脱了”啰嗦语言”的帽子,走上了现代化转型之路。这些语法特性使得日常开发更高效、代码更简洁,也更易于维护。

未来的 Java 不再只是”企业级”稳重代名词,它正在变得更轻盈、更聪明——值得每一位开发者重新审视与拥抱。

文章目录
  1. 1. 语法新特性一览
    1. 1.1. 1. switch 表达式:不再”陷阱重重”
      1. 1.1.1. 痛点
      2. 1.1.2. 新特性(JEP 325/354/361)
      3. 1.1.3. 示例
    2. 1.2. 2. 文本块(Text Blocks):三引号带来的优雅字符串
      1. 1.2.1. 痛点
      2. 1.2.2. 新特性(JEP 355/368/378)
      3. 1.2.3. 示例
    3. 1.3. 3. instanceof 模式匹配:更聪明的类型判断
      1. 1.3.1. 痛点
      2. 1.3.2. 新特性(JEP 305,JDK 16):
      3. 1.3.3. 示例
    4. 1.4. 4. record 类:轻松定义数据载体
      1. 1.4.1. 痛点
      2. 1.4.2. 新特性(JEP 384,JDK 16)
      3. 1.4.3. 示例
    5. 1.5. 5. 密封类(Sealed Classes):限制继承范围
      1. 1.5.1. 痛点
      2. 1.5.2. 新特性(JEP 360,JDK 17)
      3. 1.5.3. 示例
  2. 2. web 应用中的实际使用
    1. 2.1. 1. 使用 record 定义响应对象与 DTO
    2. 2.2. 2. 使用 sealed + instanceof 进行订单结果建模和处理
    3. 2.3. 3. 使用 switch 表达式处理支付类型
    4. 2.4. 4. 使用文本块生成 SQL 或消息模板
    5. 2.5. 5. Controller 层综合调用示例
    6. 2.6. 总结
  3. 3. 总结一览表
  4. 4. 写在最后