2020 年 3 月 17 日,JDK / Java 14 正式 GA(General Available)。這是自從 Java 採用六個月一次的發佈週期以後的第五次發佈。html
此版本包含的 JEP Java/JDK Enhancement Proposals JDK 加強提案)比 Java 12 和 13 加起來的還要多。總共 16 個新特性,包括兩個孵化器模塊 、三 個預覽特性、兩個棄用的功能以及兩個刪除的功能。java
安裝 JDK 14 https://www.oracle.com/technetwork/java/javase/overview/index.html程序員
安裝編譯器:IDEA 2020.1 或者 Eclipse 2020-03sql
這個特性頗有意思,由於它爲更爲通用的模式匹配打開了大門。模式匹配經過更爲簡便的語法基於必定的條件來抽取對象的組件,而 instanceof 恰好是這種狀況,它先檢查對象類型,而後再調用對象的方法或訪問對象的字段。macos
在 Java 14 以前,咱們使用 instanceof 是這樣的windows
@Test public void test01() { Object obj = "hello java14"; if (obj instanceof String) { String str = (String) obj; System.out.println(str.contains("hello")); } else { System.out.println("不是 String 類型"); } }
在 Java 14 中是這樣的,至關於將上面的第四、5行代碼簡化了,省略了強制轉化的過程,注意:「str 的做用域依舊是 if 結構內」數組
@Test public void test02() { Object obj = "hello java14"; if (obj instanceof String str) { System.out.println(str.contains("hello")); } else { System.out.println("不是 String 類型"); } }
有了該功能,能夠減小 Java 程序中顯式強制轉換的數量,從而提升生產力,還能實現更精確、簡潔的類型安全的代碼 。安全
該特性改進了 NullPointerException 的可讀性,能更準確地給出 null 變量的信息 。併發
就是這個老爺子當年發明的 null,讓成千上萬的程序員深惡痛絕,他稱本身犯了一個價值十億美金的錯誤,那就是空指針!oracle
《Java 8 實戰》中是這樣說的:
在 Java 8 中引入了 Optional,Optional 在可能爲 null 的對象上作了一層封裝,強制你思考值不存在的狀況,這樣
就能避免潛在的空指針異常 。
在 Java 14 中,對於 NPE 有了一個加強,該特性能夠更好地提示哪一個地方出現的空指針
須要咱們在運行參數上加上 -XX:+ShowCodeDetailsInExceptionMessages
開啓此功能,這個加強特性不只適用於方法調用,只要會致使 NullPointerException 的地方也都適用,包括字段的訪問、數組的訪問和賦值 。
咱們有時候須要編寫許多低價值的重複代碼來實現一個簡單的數據載體類:構造函數,訪問器,equals()、hashCode()、toString() 等。爲了不這種重複代碼,Java 14 推出了 record 。
該預覽特性提供了一種更爲緊湊的語法來聲明類。 值得一提的是,該特性能夠大幅減小定義相似數據類型時所需的樣板代碼。
使用 record 來減小類聲明語法,效果相似 lombok 的 @Data 註解, Kotlin 中的 data class 。它們的共同點是類的部分或所有狀態能夠直接在類頭中描述,而且這個類中只包含了純數據而已。
咱們聲明一個 record 類型的類
public record Person(String name, Integer age) { }
它編譯後的 class 文件以下
public final class Person extends java.lang.Record { private final java.lang.String name; private final java.lang.Integer age; public Person(java.lang.String name, java.lang.Integer age) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public java.lang.String name() { /* compiled code */ } public java.lang.Integer age() { /* compiled code */ } }
調用其屬性的時候與普通類有所不一樣
@Test public void test3(){ Person person = new Person("張三", 12); person.name(); person.age(); }
當你用 record 聲明一個類時,該類將自動擁有如下功能:
和枚舉類型同樣,記錄也是類的一種受限形式。 做爲回報,記錄對象在簡潔性方面提供了顯著的好處。
可是須要注意:
這是 JDK 12 和 JDK 13 中的預覽特性,如今是正式特性了。
咱們使用 ->
來替代之前的 :
和 break
,另外還提供了 yield
來在 block 中返回值
代碼演示:
public class SwitchExpression { public static void main(String[] args) { Season type = Season.AUTUMN; String s = switch (type) { case SPRING -> "春"; case SUMMER -> "夏"; case AUTUMN -> "秋"; case WINTER -> "冬"; default -> { System.out.println("沒有" + type + "這個選項"); yield "error"; } }; } enum Season { SPRING, SUMMER, AUTUMN, WINTER } }
在 Java 中,一般須要使用 String 類型表達 HTML XML SQL 或 JSON 等格式的字符串,在進行字符串賦值時須要進行轉義和鏈接操做,而後才能編譯該代碼,但這種表達方式難以閱讀而且難以維護。
因而在 JDK13 中引入了 text blocks,JDK 14 進行了第二輪 preview,JDK14 的版本主要增長了兩個功能,分別是\
和 \s
例如咱們要寫一個 sql 語句,使用普通的字符串是這樣的,這是比較簡單的語句,若是複雜一點,簡直不堪入目
@Test public void test1() { String sql = "SELECT name, age\n" + "FROM user\n" + "WHERE age = 19"; System.out.println(sql); }
使用了代碼塊是這樣的,可讀性變高了
@Test public void test2(){ String sql = """ SELECT name, age FROM user WHERE age = 19 """; System.out.println(sql); }
可是運行上述代碼能夠看出,代碼塊裏寫的是什麼格式就會輸出什麼格式,若是咱們想讓它只輸出一行,可讀性也高呢?
這時,咱們可使用 JDK 14 新加的 \
(取消換行)和 \s
(一個空格)
@Test public void test3(){ String sql = """ SELECT name, age \ FROM user\s\ WHERE age = 19\s\ """; System.out.println(sql); }
JDK 官方給出將這個 GC 組合標記爲 Deprecate 的理由是:這個 GC 組合須要大量的代碼維護工做,而且,這個 GC 組合不多被使用。由於它的使用場景應該是一個很大的 Young 區配合一個很小的 Old 區,這樣的話, Old 區用 SerialOldGC 去收集時停頓時間咱們才能勉強接受 。
廢棄了 parallel young generation GC 與 SerialOld GC 的組合( XX:+UseParallelGC 與 XX: UseParallelOldGC 配合開啓 ),如今使用 -XX:+UseParallelGC -XX:-UseParallelOldGC
或者 -XX:-UseParallelOldGC
都會出現以下警告:
Java HotSpot(TM) 64 Bit Server VM warning: Option UseParallelOldGC was deprecated in version 14.0 and will likely be removed in a future release.
該來的總會來,自從 G1 基於 Region 分代 )橫空 出世後, CMS 在 JDK9 中就被標記爲 Deprecate 了( JEP 291: Deprecate the Concurrent Mark Sweep (CMS) Garbage Collector)
CMS 的弊端:
上述的這些問題,尤爲是碎片化問題,給你的 JVM 實例就像埋了一顆炸彈。說不定哪次就在你的業務高峯期來一次 FGC。當 CMS 中止工做時,會把 Serial Old GC 做爲備選方案,而 Serial Old GC 是 JVM 中性能最差的垃圾回收方式,停頓個幾秒鐘,上十秒都有可能 。
移除了 CMS 垃圾收集器,若是在 JDK14 中使用 XX:+UseConcMarkSweepGC
的話,JVM 不會報錯,只是給出一個 warning 信息。
先看一下 ZGC 的恐怖性能,它能夠在儘量對吞吐量影響不大的前提下,實如今任意堆內存大小下均可以把垃圾收集的停頓時間限制在十毫秒之內的低延遲。
JEP 364:ZGC 應用在 macOS 上、JEP 365:ZGC 應用在 Windows 上
JDK14 以前, ZGC 僅 Linux 才支持 。儘管許多使用 ZGC 的用戶都使用類 Linux 的環境,但在 Windows 和 macOS 上,人們也須要 ZGC 進行開發部署和測試。許多桌面應用也能夠從 ZGC 中受益。所以, ZGC 特性被移植到了 Windows 和 macOS 上。
使用方式:-XX:+UnlockExperimentalVMOptions -XX:+UseZGC
雖然 ZGC 還在試驗狀態,沒有完成全部特性,但此時性能已經至關亮眼,用「使人震驚、革命性」來形容,不爲過。將來將在服務端、大內存、低延遲應用的首選垃圾收集器。
有幾個不重要的新特性沒有列舉,可自行查看相關資料
本文大部分的資料來源於此視頻的課件:https://www.bilibili.com/video/BV1tC4y147US