JDK17前后寫法超詳細對比(差點沒認出是Java)
Java,一直被開發(fā)者戲稱為“啰嗦”,但從 JDK 12 到 JDK 17,這門語言發(fā)生了顯著變化。多個語法層面的增強讓 Java 更加簡潔、表達力更強,也更接近現(xiàn)代語言的風格。本文將帶你梳理這六個版本中 Java 的關(guān)鍵語法演進。
語法新特性一覽
1.switch表達式:不再“陷阱重重”
痛點
傳統(tǒng) switch 不支持返回值,且 break 的遺漏常導致 bug。
新特性(JEP 325/354/361)
switch可作為表達式返回值- 引入箭頭語法(
->) - 支持多標簽匹配
- 使用
yield顯式返回值
示例
對 HTTP 狀態(tài)碼進行分類處理,例如:構(gòu)建統(tǒng)一響應消息或記錄錯誤日志。
String result = switch (statusCode) {
case 200 -> "OK";
case 404 -> "Not Found";
case 500 -> {
logError();
yield "Server Error";
}
default -> "Unknown";
};? 優(yōu)勢:簡潔、安全、不易出錯,便于表達邏輯分支。
2. 文本塊(Text Blocks):三引號帶來的優(yōu)雅字符串
痛點
傳統(tǒng)多行字符串使用 \n 和拼接,代碼難讀難維護。
新特性(JEP 355/368/378)
- 多行字符串使用
"""定義 - 自動處理縮進和換行
- 支持行連接符
\
示例
構(gòu)建 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());? 優(yōu)勢:更易編寫 JSON、SQL、HTML 等嵌入式文本內(nèi)容。
3.instanceof模式匹配:更聰明的類型判斷
痛點
類型判斷后必須顯式強轉(zhuǎn),重復又冗余。
新特性(JEP 305,JDK 16):
- 支持
instanceof時綁定變量
示例
處理請求參數(shù)、事件派發(fā)、策略模式中類型判斷。
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");
}
}? 優(yōu)勢:去除顯式強轉(zhuǎn),更易讀、易寫、安全。
4.record類:輕松定義數(shù)據(jù)載體
痛點
定義一個 POJO 需要寫大量樣板代碼(構(gòu)造器、getter、equals 等)。
新特性(JEP 384,JDK 16)
- 一行代碼定義不可變數(shù)據(jù)類
- 自動生成構(gòu)造器、訪問器、
equals、hashCode、toString
示例
用于接口響應對象、查詢結(jié)果封裝、消息體定義
示例1-接口響應
public record ApiResponse<T>(int code, String message, T data) {}
ApiResponse<User> response = new ApiResponse<>(200, "OK", user);示例2-封裝查詢結(jié)果
public record UserSummary(String name, int postCount) {}
List<UserSummary> summaries = userRepository.getSummaries();? 優(yōu)勢:專為數(shù)據(jù)建模而生,簡潔且不易出錯。
5. 密封類(Sealed Classes):限制繼承范圍
痛點
接口或抽象類可以被任意擴展,無法控制子類范圍。
新特性(JEP 360,JDK 17)
- 使用
sealed修飾類/接口 - 顯式聲明允許繼承的子類(使用
permits)
示例
用于建模流程狀態(tài)、支付狀態(tài)、登錄結(jié)果、事件分發(fā)等,確保所有子類都是受控的。
支付狀態(tài)
public sealed interface PaymentResult permits Success, Failure {}
public final class Success implements PaymentResult {
String transactionId;
// ...
}
public final class Failure implements PaymentResult {
String reason;
// ...
}處理支付結(jié)果:
void handle(PaymentResult result) {
if (result instanceof Success s) {
log("Success: " + s.transactionId());
} else if (result instanceof Failure f) {
log("Failure: " + f.reason());
}
}? 優(yōu)勢:提供受控擴展,便于在模式匹配和狀態(tài)建模中使用。
web應用中的實際使用
我們假設(shè)web應用有以下功能:用戶提交訂單后,系統(tǒng)處理訂單并返回處理結(jié)果(成功、庫存不足、支付失敗等狀態(tài))。
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/構(gòu)造器;
- 天然不可變,適合并發(fā)和函數(shù)式風格。
2. 使用sealed+instanceof進行訂單結(jié)果建模和處理
文件: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 中處理結(jié)果:
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("未知結(jié)果類型");
}? 優(yōu)點:
- 明確約束返回類型;
- 避免非法實現(xiàn)或擴展;
- 結(jié)合
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;
};
}? 優(yōu)點:
- 替代 if-else,代碼更整潔;
- 編譯器檢查是否遺漏分支。
4. 使用文本塊生成 SQL 或消息模板
?? 在 Repository 中寫動態(tài) SQL:
String sql = """
SELECT * FROM orders
WHERE user_id = ?
AND created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
ORDER BY created_at DESC
""";?? 發(fā)送郵件或通知模板:
String content = """
親愛的用戶,您的訂單已成功創(chuàng)建:
訂單編號:%s
總金額:%.2f 元
感謝您的購買!
""".formatted(orderNo, totalAmount);? 優(yōu)點:
- 無需拼接;
- 保持結(jié)構(gòu)清晰,適合業(yè)務模板開發(fā)。
5. Controller 層綜合調(diào)用示例
@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);
}
}綜合收益總結(jié)
| 特性 | 實際作用 | 模塊 |
|---|---|---|
record | 快速構(gòu)建不可變 DTO 與響應體 | Controller/DTO |
sealed | 精確限定子類,建模業(yè)務狀態(tài) | Service/Domain |
instanceof 模式匹配 | 簡潔判斷不同業(yè)務返回類型 | Service |
switch 表達式 | 優(yōu)雅地分發(fā)策略/狀態(tài)處理 | Service |
| 文本塊 | 結(jié)構(gòu)化模板與 SQL 管理更清晰 | Repository/通知模板 |
總結(jié)一覽表
新特性總結(jié):
| 特性 | JEP | Java版本 | 優(yōu)勢 |
|---|---|---|---|
switch 表達式 | 325/354/361 | 12-14 | 表達式化、安全簡潔 |
| 文本塊 | 355/368/378 | 13-15 | 編寫多行字符串更自然 |
instanceof 模式匹配 | 305 | 16 | 去除強轉(zhuǎn),增強可讀性 |
record 類 | 384 | 16 | 快速定義不可變數(shù)據(jù)類 |
| 密封類 | 360 | 17 | 限制繼承,提高建模安全性 |
最佳使用場景總結(jié):
| 特性 | 實踐推薦場景 | 說明 |
|---|---|---|
switch 表達式 | 狀態(tài)判斷、分支處理、枚舉映射 | 替代復雜 if-else |
| 文本塊 | SQL/HTML/JSON模板、配置文件構(gòu)造 | 可讀性強 |
instanceof 模式匹配 | 類型分發(fā)、策略切換、事件處理 | 精簡類型判斷 |
record 類 | 響應對象、DTO、只讀配置結(jié)構(gòu)體 | 最適合不可變數(shù)據(jù) |
| 密封類 | 狀態(tài)機建模、業(yè)務結(jié)果分類、事件系統(tǒng) | 編譯時安全的繼承控制 |
寫在最后
從 JDK12 到 JDK17,Java 逐步擺脫了“啰嗦語言”的帽子,走上了現(xiàn)代化轉(zhuǎn)型之路。這些語法特性使得日常開發(fā)更高效、代碼更簡潔,也更易于維護。
未來的 Java 不再只是“企業(yè)級”穩(wěn)重代名詞,它正在變得更輕盈、更聰明——值得每一位開發(fā)者重新審視與擁抱。
到此這篇關(guān)于JDK17前后寫法超詳細對比的文章就介紹到這了,更多相關(guān)JDK17前后寫法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java之synchronized(含與ReentrantLock的區(qū)別解讀)
文章主要介紹了`synchronized`和`ReentrantLock`的區(qū)別,包括它們的實現(xiàn)原理、公平性、靈活性、可中斷性等方面,同時,文章詳細解釋了`synchronized`的使用方法,包括修飾實例方法、靜態(tài)方法和代碼塊的情況,以及如何分析代碼是否互斥和可重入性2025-01-01
IDEA?2020.3最新永久激活碼(免費激活到?2099?年,親測有效)
分享一下?IntelliJ?IDEA?2020.3.1?最新激活注冊碼,破解教程如下,可免費激活至?2099?年,親測有效,本文給大家分享兩種方法,感興趣的朋友參考下吧2021-01-01
SpringBoot Maven打包如何根據(jù)環(huán)境排除文件
文章介紹了在SpringBoot項目中,根據(jù)不同的環(huán)境(開發(fā)、測試、生產(chǎn))進行JSP文件打包處理的方法,通過配置`pom.xml`文件中的``標簽,可以實現(xiàn)開發(fā)環(huán)境保留`index.jsp`文件,測試環(huán)境和生產(chǎn)環(huán)境排除該文件2024-12-12

