JDK14新特性(What's New In JDK 14)

2020年3月17日,Java 14(Java SE 14)及其Java開發工具包14(JDK 14)開源發佈。本文主要記錄了JDK14的16個新特性。

本文的IDE爲IDEA2020.1,JDK14是通過IDE下載的Open JDK.

Pattern Matching for instanceof (Preview)

instanceof的模式匹配(預覽版)

String s = "instance";
//before jdk14
if (s instanceof String) {
    String str = s;
    System.out.println("before jdk14:" + str);
}
//in jdk14
if (s instanceof String str) {
    System.out.println("before jdk14:" + str);
}
if (s instanceof String str && str.equals("instance")) {
    System.out.println("TRUE");
}

僅當object不爲null時,instanceOf纔會匹配,然後僅將其分配給str。 在instanceof中使用模式匹配應減少Java程序中顯式強制轉換的總數。

Non-Volatile Mapped Byte Buffers (Incubator)

新增了java.base/jdk/internal/misc/ExtendedMapMode.java以支持MappedByteBuffer訪問non-volatile
memory (NVM)。

從JDK1.4開始,Java引入了NIO文件相關的API,帶有MappedByteBuffer的FileChannel將文件數據的一部分加載到虛擬內存中,然後引入了稱爲Path的新增強功能。 當我們使用Java NIO時,Path是一個接口,它將java.io.File類替換爲文件或目錄的表示形式。
現在,Java 14對MappedByteBuffer進行了增強,以將部分文件數據加載到非易失性內存(NVM)中。 非易失性存儲器或非易失性存儲器是計算機存儲器,即使關閉電源(例如ROM(只讀存儲器),閃存,硬盤等存儲設備)也不會丟失/刪除數據。 如果像RAM一樣關閉電源,則無法保留數據。 唯一需要的API更改是FileChannel客戶端採用的新枚舉,以請求映射位於NVM支持的文件系統而不是傳統文件存儲系統上的文件。

Helpful NullPointerExceptions

JVM生成的NullPointerExceptions(NPE)異常消息的改進。可以更好地提示哪個地方出現的空指針,需要通過-XX:+ShowCodeDetailsInExceptionMessages開啓。 對於程序過早終止,這將對開發人員和支持人員有幫助的信息。 由於NPE幾乎可以出現在程序中的任何位置,因此嘗試捕獲它們並從中恢復通常是不切實際的。

//NullPointerExceptions
pojo p = new pojo(null);
System.out.println(p.getApple().getColor());

在此之前,報錯時這樣的:
在這裏插入圖片描述
現在在運行參數中配置:-XX:+ShowCodeDetailsInExceptionMessages,開啓Helpful NullPointerExceptions:
在這裏插入圖片描述
開啓之後,運行結果是這樣的:
在這裏插入圖片描述
如圖所示,準確的告知了我們哪個變量爲null。

Switch Expressions (Standard)

JDK14擴展了switch語句,在JDK12種已引入,在JDK14中變爲了正式版。現在的case中使用->來替代以前的:+break,而且提供了yield來在block中返回值;

//switch
//before JDK14
Calendar calendar = Calendar.getInstance();
Integer today = calendar.get(Calendar.DAY_OF_WEEK);
String weekday = "";
switch (today) {
    case Calendar.MONDAY:
    case Calendar.TUESDAY:
    case Calendar.WEDNESDAY:
    case Calendar.THURSDAY:
    case Calendar.FRIDAY:
        weekday = "weekday";
        break;
    case Calendar.SATURDAY:
    case Calendar.SUNDAY:
        weekday = "weekend";
        break;
    default:
        throw new IllegalStateException("Unexpected value: " + today);
}
System.out.println("Before JDK14:"+weekday);
//in JDK14
weekday = switch (today) {
    case Calendar.MONDAY, Calendar.TUESDAY, Calendar.WEDNESDAY, Calendar.THURSDAY, Calendar.FRIDAY -> "weekday";
    case Calendar.SATURDAY, Calendar.SUNDAY -> "weekend";
    default -> {
        yield "unknown";
        //throw new IllegalStateException("Unexpected value: " + Calendar.DAY_OF_WEEK);
    }
};
System.out.println("JDK14:"+weekday);

Packaging Tool (Incubator)

打包工具(孵化中)

JDK14引入了jdk.incubator.jpackage.jmod,它基於JavaFX javapackager tool構建,目的在於創建一個簡單的打包工具。
jpackage工具將Java應用程序捆綁到特定於平臺的程序包中,其中包含所需的所有依賴項。作爲一組普通的JAR文件或作爲模塊的集合。
可以用於構建以下文件格式的安裝文件:

  • Linux: deb and rpm
  • macOS: pkg and dmg
  • Windows: msi and exe

非模塊化的app的構建示例如下:

jpackage --name myapp --input lib --main-jar main.jar

NUMA-Aware Memory Allocation for G1

NUMA-Aware Memory Allocation(NUMA)是一種將微處理器集羣配置爲多處理系統的方法,因此可以在本地共享內存,可以提高性能並擴展系統的功能。
Java 14提供了可識別NUMA的內存分配功能,以提高大型計算機上的G1性能。
G1的堆組織爲固定大小區域的集合。一個區域通常是一組物理頁面,儘管使用大頁面(通過-XX:+ UseLargePages)時,多個區域可能組成一個物理頁面。
如果指定了+ XX:+ UseNUMA選項,則在初始化JVM時,區域將平均分佈在可用NUMA節點的總數上。

JFR Event Streaming

JDK11引入了JFR,使用的時候先dump到磁盤上然後再分析;而在JDK14則支持stream方式來進行進程內和進程外應用程序的持續性監控。

Records (Preview)

JDK14引入了預覽版本的record類型。在開發中,我們需要編寫許多重複代碼,編寫簡單的實體類:構造函數,getter 和 setter,equals(),hashCode(),toString()等。爲避免這種重複代碼,Java計劃使用Records。

在此前的實體類:
在這裏插入圖片描述
而在JDK14的預覽版中,只需一行代碼就可以實現等同於以上的效果。
在這裏插入圖片描述
讓我們來看看編譯後的AppleRecord實體類,它長這樣:
在這裏插入圖片描述
可以看到AppleRecord繼承了java.lang.Record,而且生成了final的hashCode()及equals()方法,但是卻沒有了setter方法,getter方法也省略了get前綴。

Deprecate the Solaris and SPARC Ports

廢棄Solaris / SPARC,Solaris / x64和Linux / SPARC端口,以便將來刪除。

通過取消對這些端口的支持,OpenJDK社區中的貢獻者將能夠加速新功能的開發,以推動平臺向前發展。

構建配置更改

以下內容會導致嘗試配置Solaris和/或SPARC:

$ bash ./configure
...
checking compilation type... native
configure: error: The Solaris and SPARC ports are deprecated and may be removed in a future release. \
Use --enable-deprecated-ports=yes to suppress this error.
configure exiting with result code 1
$

新的–enable-deprecated-ports = yes 配置項將消除該錯誤並繼續。

$ bash ./configure --enable-deprecated-ports=yes
...
checking compilation type... native
configure: WARNING: The Solaris and SPARC ports are deprecated and may be removed in a future release.
...
Build performance summary:
* Cores to use:   32
* Memory limit:   96601 MB

爲Solaris和SPARC(包括Solaris / SPARC,Solaris / x64,Linux / SPARC)配置構建時,將發出錯誤/警告。

Remove the Concurrent Mark Sweep (CMS) Garbage Collector

移除了CMS垃圾收集器。此更新將停用CMS編譯,從源樹中刪除gc / cms目錄的內容,並刪除僅CMS選項。如果在JDK14中使用-XX:+UseConcMarkSweepGC的話,會出現警告,但是不會退出而是以默認的垃圾收集器運行。

ZGC on macOS (experimental)

之前的ZGC只能在linux上使用,現在mac上也能使用了。

ZGC on Windows (experimental)

之前的ZGC只能在linux上使用,現在windows(不能低於1803版本)上也能使用。

Deprecate the ParallelScavenge + SerialOld GC Combination

廢棄了parallel young generation GC與SerialOld GC的組合( -XX:+UseParallelGC與-XX:-UseParallelOldGC配合開啓),現在使用-XX:+UseParallelGC -XX:-UseParallelOldGC或者-XX:-UseParallelOldGC都會出現告警。

Remove the Pack200 Tools and API

移除了Pack200 API。

Text Blocks (Second Preview)

在Java中,要將HTML,XML,SQL或JSON代碼片段嵌入到代碼中通常很難閱讀且難以保留,並且爲了克服此問題,Java 14引入了Text Block。
JDK13引入的text blocks進行第二輪預覽,JDK14的版本主要增加了兩個escape sequences,分別是 <line-terminator>與\s escape sequence。

由三個英文雙引號(""")開始/結束。與字符串文字中的字符不同,內容可以直接包含雙引號字符。 允許在文本塊中使用\“,但不是必需的或不建議使用。"""可以使字符可以不轉義出現,並且還可以從視覺上區分文本塊和字符串文字。

//HTML without text block
String html = "<html>\n" +
        "    <body>\n" +
        "        <p>Hello, world</p>\n" +
        "    </body>\n" +
        "</html>\n";
//HTML with text block
String htmlTextBlock = """
      <html>
          <body>
              <p>Hello, world</p>
          </body>
      </html>
      """;

Foreign-Memory Access API (Incubator)

提供了孵化版本的API用於操縱堆外內存。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章