我還在生產玩 JDK7,JDK 15 卻要來了!|新特性嚐鮮

自從 JDK9 以後,每一年 3 月與 9 月 JDK 都會發佈一個新的版本,而2020 年 9 月即將引來 JDK15。javascript

恰巧 IDEA 每四五個月會升級一個較大的版本,每次升級以後都會支持最新版本 JDK 引入的新功能。java

這幾天升級了 IDEA,順便體驗了一下 JDK15 的新特性。shell

雖然我知道大家可能跟我同樣JDK8 都還沒用熟,可是無妨,看看新版本 JDK 來酸一下。編輯器

Text Blocks 最終定板

以前版本的 JDK,若是咱們須要插入 HTMLXMLSQLJSON 片斷,很是麻煩,須要對裏面符號進行各類轉義。ide

因此我每次都會在其餘編輯器將 HTML ,XML 等編輯好,而後直接複製到 IDEA 中,IDEA 自動會對這些字符轉義。學習

每次複製進去就變成上圖的效果,若是上面字符再多點,閱讀起來就會更難,而且難以維護。優化

所幸 IDEA 提供了一個 Inject Language 功能,咱們能夠在裏面快速方便的編輯。idea

Java 開發者也關注到這個問題,他們在 JDK13 引入的一個新的預覽特性「Text Blocks」,可使用三引號將複雜的字符串賦值,從而讓咱們從各類轉義中解脫出來,能夠更加方便的編輯字符串。spa

這個功能在其餘語言仍是比較常見的,好比 Python 等。.net

Text Blocks 新功能在 JDK14 再次以預覽功能引入,最終在 JDK15 成爲新版本的正式功能。

下面咱們來對比一下使用 Text Blocks 與以前區別:

Html

SQL

JS

Records (Second Preview)

JDK14 引入一個新的預覽特性 record 語法,能夠快速建立一個純數據類,而且不用去生成 gettertoString 等。

使用下面的語法就能夠快速建立一個數據類:

public record Point(int x,int y) {
}

JDK15 是 record 這個語法的第二次預覽,這個版本增長一個新的功能 「local record」,能夠在一個方法在快速建立一個類,以便於方法中業務邏輯計算。

在如下示例中,使用本地記錄 MerchantSales 對商人和每個月銷售額的彙總進行建模,使用此記錄可提升如下流操做的可讀性:

下面例子的中咱們新建一個類 MerchantSales,而後按照銷售人員對每個月的銷售額彙總排序。

List<Merchant> findTopMerchants(List<Merchant> merchants, int month) {
    // Local record
    record MerchantSales(Merchant merchant, double sales) {}

    return merchants.stream()
        .map(merchant -> new MerchantSales(merchant, computeSales(merchant, month)))
        .sorted((m1, m2) -> Double.compare(m2.sales(), m1.sales()))
        .map(MerchantSales::merchant)
        .collect(toList());
}

原先若是須要使用這種功能,咱們不得不建立一個內部類,後續可能不再會用到,使用 local record就解決這個尷尬的問題。

除了 local record 咱們還能夠建立 local enums 以及 local interface

// local enums
public void organisePeople(List<Person> people) {
    enum Role {
        Employee, Customer, Both, None
    }
    HashMap<Role, List<Person>> peopleByRole = new HashMap<>();
    people.stream()
            .filter(Person::isCustomer)
            .forEach(person -> peopleByRole.computeIfAbsent(Role.Customer, role -> new ArrayList<>())
                    .add(person));
    // 其餘業務邏輯

}
// local interface
public void localInterface() {
    interface MyInterface {
        void doSomething();
    }
    MyInterface testInterface = new MyInterface() {
        @Override
        public void doSomething() {
            System.out.println("Hello World!");
        }
    };
    // 其餘業務邏輯

}

最後使用這個特性須要注意一點,local record , local enums ,local interface 建立都是一個局部變量,是不能被傳遞其餘方法引用。

Pattern Matching for instanceof (Second Preview)

咱們應該都看到過下面這種代碼:

if (obj instanceof String) {
    String str = (String) obj;
    // use str
}

上面代碼意圖很是簡單,當 obj 對象是 String 類,就將其強制轉換,而後進行其餘業務操做。

這種寫法,類型轉換仍是比較繁瑣,Pattern Matching for instanceof 這個新語法特性,能夠幫咱們省略這種類型轉換動做。這是一個在 JDK14 引入一個預覽特性,JDK 15 開始第二次預覽。

上面的代碼使用 pattern matcher,就能夠被修改以下:

if (obj instanceof String s) {
    s.contains("T");
} else {
    // 編譯錯誤
    //s.contains("T");
}

另外若是在 IDEA 中還能夠提示咱們將代碼轉化成 pattern matcher

你們應該都看過 Effective Java 這本神書吧,裏面第八條關於 Equals 有一個例子:

使用 pattern matcher 咱們就可使用下面更加清晰的代碼代替:

Sealed Classes (Preview)

Java 中一個正常普通類/接口容許被其餘子類繼承/實現,可是有時在平常開發中,咱們可能但願只有特定的類才能繼承擴展。

現有的 Java 語法中存在一些方法,能夠限制子類擴展,好比說:咱們可使用 final 修飾類

public final class String

不過這樣以後,咱們就沒辦法再繼承這個類。

其次咱們能夠限制的類的範圍,好比說不使用 public 修飾類/接口,即便用 default 範圍,這樣只有同一個包才能繼承/實現。

interface DefaultExample {
}

不過使用這種方式,又很尷尬,這個類就沒法被其餘包使用。

爲了解決上述問題,JDK 15 引入一個新的預覽特性 Sealed Classes,便可以限定類的擴展,也能夠被外部使用。

public sealed class Shape
    permits Circle, Rectangle, Square {...}

使用 sealed 修飾以後,Shape 類只能被 CircleRectangleSquare繼承,不再能被其餘類繼承。

同時 Shape 的子類存在一些限制,必須使用 final 修飾,代表這個類沒法再被擴展:

public final class Circle extends Shape {...}

或者繼續使用 sealed 表示子類只能被指定類繼承:

public sealed class Rectangle extends Shape 
    permits TransparentRectangle, FilledRectangle {...}
public final class TransparentRectangle extends Rectangle {...}

又或者說使用 non-sealed 代表這個子類不限制子類擴展,能夠被其餘任何類擴展實現。

另外 sealed class 還能夠跟上述 record 語法一塊兒使用。

public sealed interface Expr
    permits ConstantExpr, PlusExpr, TimesExpr, NegExpr {...}

public record ConstantExpr(int i)       implements Expr {...}
public record PlusExpr(Expr a, Expr b)  implements Expr {...}
public record TimesExpr(Expr a, Expr b) implements Expr {...}
public record NegExpr(Expr e)           implements Expr {...}

ZGC

ZGC(Z Garbage Collector) 這是一款在 JDK11 引入的的具備實驗性質的低延遲的 GC 收集器。

這款 GC 收集器的但願在儘量對吞吐量影響不大的前提下,實如今任意堆內存大小均可以把垃圾收集器的停頓時間限制在十毫秒之內的低延遲。

ZGC 通過這兩三年的迭代優化,終於在 JDK15 中正式引入,標誌着 ZGC 能夠正式應用於生產應用。

JDK15 中默認虛擬機仍是 G1,若是須要使用 ZGC,須要在啓動參數中加入以下參數:

-XX:+UseZGC command-line

最後

原本這篇文章是準備寫下 IDEA 2020.2 新版本特性,順帶介紹一下 JDK15 新特性的。

但是沒想到寫着寫着,JDK15 相關的篇幅就過長了,因此就單獨拿出來了。

最後,最後,JDK 都發布到 15 了,而我卻還在用 JDK 7 ,真是個悲傷的故事,逃了逃了!

我是樓下小黑哥,天天學習一點點,成長億點點!!

參考連接

https://openjdk.java.net/proj...

歡迎關注個人公衆號:程序通事,得到平常乾貨推送。若是您對個人專題內容感興趣,也能夠關注個人博客: studyidea.cn

相關文章
相關標籤/搜索