記錄jdk17相對於jdk8增加的一下主要語法糖和新特性

2023-11-15 18:00:37

  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)

  • 擴充套件的 switchswitch 可以作為表示式使用,並支援 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 關鍵字:用於宣告不可變的資料物件,自動為您生成構造器、存取器、equalshashCodetoString 方法。

  • 不可變性:記錄範例的狀態是不可變的,一旦建立,其欄位值就不能更改。
  • 資料載體:記錄被設計為簡單的資料載體,用於傳輸資料,不推薦在其中新增複雜的業務邏輯。
//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 表示式時。
  • 使用方法

    1. 宣告密封類:在類或介面宣告中使用 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 { /*...*/ }