jdk17 釋出已經好久了,作為java的長期支援版本,引入了許多有趣且實用的新特性。這些特性不僅提高了開發效率,還增強了語言的表現力和安全性。並且是SpringBoot 3.0以後版本的硬性要求,之後勢必會是java開發的主要版本。
經過我個人的測試體驗,在 Java 17 環境中執行使用早期 Java 版本(如 Java 8)編寫的程式碼和庫通常是沒有問題的。這裡簡單記錄一下jdk17 相比較與jdk8的主要不同點
1. 區域性變數型別推斷(Java 10)
var
關鍵字:可以在區域性變數宣告中使用var
,而無需顯式宣告資料型別。Java 編譯器會根據變數的初始化值推斷其型別。var list = new ArrayList<String>(); // 無需顯式指定型別
2. Lambda 引數的區域性變數語法(Java 11)
-
Lambda 表示式中的
var
:允許在 Lambda 表示式的引數中使用var
,使得可以為引數新增註解。(var x, var y) -> x.process(y)
3. 文字塊(Java 13,正式在 Java 15)
-
多行字串文字:簡化了多行字串的處理,使用三個雙引號來界定。
- 好處:簡化了多行字串的處理,特別是在處理 JSON、HTML 或 SQL 時。
String json = """ { "name": "John", "age": 30 } """;
4. switch 表示式(Java 14,正式在 Java 17)
-
擴充套件的
switch
:switch
可以作為表示式使用,並支援yield
語句返回值。
Integer day = 2; String result = switch (day) { case MONDAY, FRIDAY, SUNDAY -> "Weekend"; case TUESDAY, THURSDAY, SATURDAY -> "Weekday"; default -> throw new IllegalStateException("Invalid day: " + day); }; System.out.println("現在是" + result);
5. 模式匹配 instanceof
(Java 16)
-
模式匹配:改進
instanceof
操作,直接在條件判斷中宣告變數。
if (obj instanceof String s) { // 可以直接使用 s System.out.println(s); }
6. 記錄型別(Java 16,正式在 Java 17)
-
record
關鍵字:用於宣告不可變的資料物件,自動為您生成構造器、訪問器、equals
、hashCode
和toString
方法。
- 不可變性:記錄例項的狀態是不可變的,一旦建立,其欄位值就不能更改。
- 資料載體:記錄被設計為簡單的資料載體,用於傳輸資料,不推薦在其中新增複雜的業務邏輯。
//record類 public record User(String name, int age) { }
使用Record宣告的User類
public static void main(String[] args) { User user = new User("張三", 18, "北京市朝陽區"); System.out.println(user.address()); System.out.println(user.name()); System.out.println(user.age()); }
7. 密封類(Java 17)
-
密封類:允許類或介面限制哪些其他類或介面可作為其子類或實現者(
sealed
,permits
關鍵字)。 - 受限的繼承:密封類允許您明確指定哪些其他類可以繼承或實現它。
- 保證的窮舉性:密封類的一個關鍵優點是它們使得型別檢查可以是窮盡的,特別是在使用模式匹配的
switch
表示式時。 -
使用方法
-
宣告密封類:在類或介面宣告中使用
sealed
關鍵字,然後使用permits
關鍵字指定允許擴充套件或實現該類或介面的所有直接子類。
-
public sealed class Shape permits Circle, Square, Rectangle { // ... }
指定子類:子類必須選擇如何繼承密封類,它們可以是 final
(不能被進一步繼承)、sealed
(指定其自己的子類)或 non-sealed
(允許開放繼承)。
public final class Circle extends Shape { /*...*/ } public sealed class Rectangle extends Shape permits FilledRectangle, EmptyRectangle { /*...*/ } public non-sealed class Square extends Shape { /*...*/ }