一篇文帶你瞭解JDK 13新特性,保姆級教程

JDK 13新特性介紹

1。1 JDK 各版本主要特性回顧

JDK Version 1。0

1996-01-23 Oak(橡樹)

初代版本,偉大的一個里程碑,但是是純解釋執行,使用外掛JIT,效能比較差,執行速度慢。

JDK Version 1。1

1997-02-19

JDBC(Java DataBase Connectivity);

支援內部類;

RMI(Remote Method Invocation) ;

反射;

Java Bean;

JDK Version 1。2

集合框架;

JIT(Just In Time)編譯器;

對打包的Java檔案進行數字簽名;

JFC(Java Foundation Classes), 包括Swing 1。0, 拖放和Java2D類庫;

Java外掛;

JDBC中引入可滾動結果集,BLOB,CLOB,批次更新和使用者自定義型別;

Applet中新增聲音支援。

同時,Sun釋出了 JSP/Servlet、EJB規範,以及將Java分成了 J2EE、J2SE和J2ME。 這表明了 Java開始向企業、桌面

應用和移動裝置應用3大領域挺進。

JDK Version 1。3

2000-05-08 Kestrel(紅隼)

Java Sound API;

jar檔案索引;

對Java的各個方面都做了大量最佳化和增強;

JDK Version 1。4

2004-02-06 Merlin(隼)

XML處理;

Java列印服務;

Logging API;

Java Web Start;

JDBC 3。0 API;

斷言;

Preferences API;

鏈式異常處理;

支援IPV6;

支援正則表示式;

引入Imgae I/O API。

JAVA 5

2004-09-30 Tiger(老虎)

泛型;

增強迴圈,可以使用迭代方式;

自動裝箱與自動拆箱;

型別安全的列舉;

可變引數;

靜態引入;

元資料(註解);

Instrumentation;

JAVA 6

2006-12-11 Mustang(野馬)

支援指令碼語言;

JDBC 4。0API;

Java Compiler API;

可插拔註解;

增加對Native PKI(Public Key Infrastructure), Java GSS(Generic Security Service),Kerberos和LDAP(Lightweight Directory Access Protocol)支援;

繼承Web Services;

JAVA 7

2011-07-28 Dolphin(海豚)

switch語句塊中允許以字串作為分支條件;

在建立泛型物件時應用型別推斷;

在一個語句塊中捕獲多種異常;

支援動態語言;

支援try-with-resources(在一個語句塊中捕獲多種異常);

引入Java NIO。2開發包;

數值型別可以用二進位制字串表示,並且可以在字串表示中新增下劃線; 鑽石型語法(在建立泛型物件時應用型別推斷);

null值得自動處理;

JAVA 8

2014-03-18

Lambda 表示式 − Lambda允許把函式作為一個方法的引數(函式作為引數傳遞進方法中。

方法引用 − 方法引用提供了非常有用的語法,可以直接引用已有Java類或物件(例項)的方法或構造器。與lambda聯合使用,方法引用可以使語言的構造更緊湊簡潔,減少冗餘程式碼。

預設方法 − 預設方法就是一個在接口裡面有了一個實現的方法。

新工具 − 新的編譯工具,如:Nashorn引擎 jjs、 類依賴分析器jdeps。

Stream API −新新增的Stream API(java。util。stream) 把真正的函數語言程式設計風格引入到Java中。

Date Time API − 加強對日期與時間的處理。

Optional 類 − Optional 類已經成為 Java 8 類庫的一部分,用來解決空指標異常。

Nashorn, JavaScript 引擎 − Java 8提供了一個新的Nashorn javascript引擎,它允許我們在JVM上執行特定的javascript應用。

JAVA 9

2017-09-22

模組系統:模組是一個包的容器,Java 9 最大的變化之一是引入了模組系統(Jigsaw 專案)。 REPL (JShell):互動式程式設計環境。

HTTP 2 客戶端:HTTP/2標準是HTTP協議的最新版本,新的 HTTPClient API 支援 WebSocket 和 HTTP2 流以及伺服器推送特性。

改進的 Javadoc:Javadoc 現在支援在 API 文件中的進行搜尋。另外,Javadoc 的輸出現在符合相容 HTML5 標準。

多版本相容 JAR 包:多版本相容 JAR 功能能讓你建立僅在特定版本的 Java 環境中執行庫程式時選擇使用的 class 版本。

集合工廠方法:List,Set 和 Map 介面中,新的靜態工廠方法可以建立這些集合的不可變例項。

私有介面方法:在介面中使用private私有方法。我們可以使用 private 訪問修飾符在介面中編寫私有方法。

程序 API: 改進的 API 來控制和管理作業系統程序。引進 java。lang。ProcessHandle 及其巢狀介面 Info 來讓開發者逃離時常因為要獲取一個本地程序的 PID 而不得不使用原生代碼的窘境。

改進的 Stream API:改進的 Stream API 添加了一些便利的方法,使流處理更容易,並使用收集器編寫複雜的查詢。

改進 try-with-resources:如果你已經有一個資源是 final 或等效於 final 變數,您可以在 try-with-resources 語句中使用該變數,而無需在 try-with-resources 語句中宣告一個新變數。

改進的棄用註解 @Deprecated:註解 @Deprecated 可以標記 Java API 狀態,可以表示被標記的 API 將會被移除,或者已經破壞。

改進鑽石運算子(Diamond Operator) :匿名類可以使用鑽石運算子(Diamond Operator)。 改進 Optional 類:java。util。Optional 添加了很多新的有用方法,Optional 可以直接轉為 stream。

多解析度影象 API:定義多解析度影象API,開發者可以很容易的操作和展示不同解析度的影象了。 改進的 CompletableFuture API : CompletableFuture 類的非同步機制可以在 ProcessHandle。onExit 方法退出時執行操作。

輕量級的 JSON API:內建了一個輕量級的JSON API

響應式流(Reactive Streams) API: Java 9中引入了新的響應式流 API 來支援 Java 9 中的響應式程式設計。

JAVA 10

2018-03-21

根據官網的公開資料,共有12個重要特性,如下:

JEP286,var 區域性變數型別推斷。

JEP296,將原來用 Mercurial 管理的眾多 JDK 倉庫程式碼,合併到一個倉庫中,簡化開發和管理過程

JEP304,統一的垃圾回收介面。

JEP307,G1 垃圾回收器的並行完整垃圾回收,實現並行性來改善最壞情況下的延遲。

JEP310,應用程式類資料 (AppCDS) 共享,透過跨程序共享通用類元資料來減少記憶體佔用空間,和減少啟動時間。

JEP312,ThreadLocal 握手互動。在不進入到全域性 JVM 安全點 (Safepoint) 的情況下,對執行緒執行回撥。最佳化可以只停止單個執行緒,而不是停全部執行緒或一個都不停。

JEP313,移除 JDK 中附帶的 javah 工具。可以使用 javac -h 代替。

JEP314,使用附加的 Unicode 語言標記擴充套件。

JEP317,能將堆記憶體佔用分配給使用者指定的備用記憶體裝置。

JEP317,使用 Graal 基於 Java 的編譯器,可以預先把 Java 程式碼編譯成原生代碼來提升效能。

JEP318,在 OpenJDK 中提供一組預設的根證書頒發機構證書。開源目前 Oracle 提供的的 Java SE 的根證書,這樣 OpenJDK 對開發人員使用起來更方便。

JEP322,基於時間定義的釋出版本,即上述提到的釋出週期。版本號為FEATURE。FEATURE。INTERIM。UPDATE。UPDATE。PATCH,分j別是大版本,中間版本,升級包和補丁版本。

JAVA 11

2018-09-25

翻譯後的新特性有:

181:Nest-Based訪問控制

309:動態類檔案常量

315:改善Aarch64 intrinsic

318:無操作垃圾收集器

320:消除Java EE和CORBA模組

321:HTTP客戶端(標準)

323:區域性變數的語法λ引數

324:Curve25519和Curve448關鍵協議

327:Unicode 10

328:飛行記錄器

329:ChaCha20和Poly1305加密演算法

330:發射一列縱隊原始碼程式

331:低開銷堆分析

332:傳輸層安全性(Transport Layer Security,TLS)1。3

333:動作:一個可伸縮的低延遲垃圾收集器 (實驗)

335:反對Nashorn JavaScript引擎

336:反對Pack200工具和API

JAVA 12

2018-09-25

翻譯後的新特性有:

189: Shenandoah: A Low-Pause-Time Garbage Collector (Experimental) :新增一個名為 Shenandoah 的垃圾回收器,它透過在 Java 執行緒執行的同時進行疏散 (evacuation) 工作來減少停頓時間。

230: Microbenchmark Suite:新增一套微基準測試,使開發者能夠基於現有的 Java Microbenchmark Harness(JMH)輕鬆測試 JDK 的效能,並建立新的基準測試。

325: Switch Expressions (Preview) :對 switch 語句進行擴充套件,使其可以用作語句或表示式,簡化日常程式碼。

334: JVM Constants API :引入一個 API 來對關鍵類檔案 (key class-file) 和執行時工件的名義描述(nominal descriptions)進行建模,特別是那些可從常量池載入的常量。

340: One AArch64 Port, Not Two :刪除與 arm64 埠相關的所有原始碼,保留 32 位 ARM 移植和 64 位 aarch64 移植。

341: Default CDS Archives :預設生成類資料共享(CDS)存檔。

344: Abortable Mixed Collections for G1 :當 G1 垃圾回收器的回收超過暫停目標,則能終止垃圾回收過程。

346: Promptly Return Unused Committed Memory from G1 :改進 G1 垃圾回收器,以便在空閒時自動將 Java 堆記憶體返回給作業系統。

1。2 JDK 各版本支援週期

一篇文帶你瞭解JDK 13新特性,保姆級教程

為了更快地迭代,Java的更新從傳統的以特性驅動的釋出週期,轉變為以時間驅動的(6 個月為週期)釋出模式 每半年釋出一個大版本,每個季度釋出一箇中間特性版本,並且承諾不會食言。透過這樣的方式,開發團隊可以把 些關鍵特性儘早合併到 JDK 之中,以快速得到開發者反饋,按照官方的說法,新的釋出週期會嚴格遵循時間點,將於每年的3月份和9月份釋出。所以 Java 11 的版本號是18。9(LTS,long term support)。Oracle 直到2023年9月都會為 Java 11 提供技術支援,而補丁和安全警告等擴充套件支援將持續到2026年。新的長期支援版本每三年釋出一次,根據後續的釋出計劃,下一個長期支援版 Java 17 將於2021年釋出

1。3 目前企業JDK版本使用現狀

在 JDK 版本的世界裡,從來都是 Oracle 發他的新版本,我們繼續用我們的老版本。三年之前用 JDK 7,後來終於升級到了 JDK 8。自從升級了沒多久,JDK 就開始了半年發一個新版本的節奏,陸續釋出了 9 、10、11、12,直到(2019年9月17日)釋出了 JDK13。

開發人員在生產中為其應用程式使用了哪些產品?我們可以看到Oracle JDK和OpenJDK在其他所有人的主導地位。2018年12月,由 Snyk 和 The Java Magazine 聯合推出釋出的 2018 JVM 生態調查報告 顯示有 70% 的使用者使用 Oracle JDK,21% 的使用者使用 OpenJDK。

一篇文帶你瞭解JDK 13新特性,保姆級教程

Java 9中的JDK進行了重大的結構更改,許多人預測這將影響遷移和採用。從結果中我們可以看到(請注意,調查是在Java 10和Java 11發行之間進行的),Java 8仍然是Java的最主要版本-十分之八的受訪者表示,他們的主要應用程式在生產中使用了Java 8。同樣重要的是,使用更新版本的非Java 8受訪者不到一半。2018 JVM 生態調查報告](https://snyk。io/blog/jvm-ecosystem-report-2018),[其中 Java 8 的使用者佔到了 79%。

一篇文帶你瞭解JDK 13新特性,保姆級教程

1。4 JDK 13詳細概述

​ 2019年9月17日,國際知名的OpenJDK開源社群釋出了Java程式語言環境的最新版本OpenJDK 13,此次更新是繼半年前 Java 12 這大版本釋出之後的一次常規版本更新,在這一版中,主要帶來了 ZGC 增強、更新 Socket 實現、Switch 表示式,文字塊更新等方面的改動、增強。

1。5 JDK 13 新特性更新列表介紹

網站:http://openjdk。java。net/projects/jdk/13/

一篇文帶你瞭解JDK 13新特性,保姆級教程

1。6 啟動IDEA建立模組整合JDK 13

去官網下載JDK 13

下載地址:https://www。oracle。com/java/technologies/javase-jdk13-downloads。html

啟動IDEA建立一個模組整合JDK 13

JDK 13新特性詳解

2。1 JEP 354 switch表示式(預覽)

引入

擴充套件switch分支選擇語句的寫法。Switch表示式在經過JDK 12的預覽之後,在JDK 13中可以繼續使用。

設計初衷

Java的switch語句是一個變化較大的語法(可能是因為Java的switch語句一直不夠強大、熟悉swift或者js語言的同學可與swift的switch語句對比一下,就會發現Java的switch相對較弱),因為Java的很多版本都在不斷地改進switch語句:JDK 12擴充套件了switch語句,使其可以用作語句或者表示式,並且傳統的和擴充套件的簡化版switch都可以使用。

JDK 12對於switch的增強主要在於簡化書寫形式,提升功能點。 下面簡單回顧一下switch的進化階段:

從Java 5+開始,Java的switch語句可使用枚舉了。

從Java 7+開始,Java的switch語句支援使用String型別的變數和表示式了。

從Java 11+開始,Java的switch語句會自動對省略break導致的貫穿提示警告。

但從JDK12開始,Java的switch語句有了很大程度的增強。

JDK 13的該JEP是從JEP 325]演變而來的。

以前的switch程式

程式碼如下:

public class Demo01{ public static void main(String[] args){ // 宣告變數score,併為其賦值為‘C’ var score = ‘C’; // 執行switch分支語句 switch (score) { case ‘A’: System。out。println(“優秀”); break; case ‘B’: System。out。println(“良好”); break; case ‘C’: System。out。println(“中”); break; case ‘D’: System。out。println(“及格”); break; case ‘E’: System。out。println(“不及格”); break; default: System。out。println(“資料非法!”); } }}

這是經典的Java 11以前的switch寫法 ,這裡不能忘記寫break,否則switch就會貫穿、導致程式出現錯誤(JDK 11會提示警告)。

JDK 13不需要break了

在JDK 12之前如果switch忘記寫break將導致貫穿,在JDK 12對switch的這一貫穿性做了改進。你只要將case後面的冒號(:)改成箭頭,那麼你即使不寫break也不會貫穿了,因此上面程式可改寫如下形式:

public class Demo02{ public static void main(String[] args){ // 宣告變數score,併為其賦值為‘C’ var score = ‘C’; // 執行switch分支語句 switch (score){ case ‘A’ -> System。out。println(“優秀”); case ‘B’ -> System。out。println(“良好”); case ‘C’ -> System。out。println(“中”); case ‘D’ -> System。out。println(“及格”); case ‘E’ -> System。out。println(“不及格”); default -> System。out。println(“成績資料非法!”); } }}

上面程式碼簡潔很多了。

JDK 13的switch表示式

JDK 12之後的switch甚至可作為表示式了——不再是單獨的語句。例如如下程式。

public class Demo03 { public static void main(String[] args) { // 宣告變數score,併為其賦值為‘C’ var score = ‘C’; // 執行switch分支語句 String s = switch (score) { case ‘A’ -> “優秀”; case ‘B’ -> “良好”; case ‘C’ -> “中”; case ‘D’ -> “及格”; case ‘F’ -> “不及格”; default -> “成績輸入錯誤”; }; System。out。println(s); }}

上面程式直接將switch表示式的值賦值給s變數,這樣switch不再是一個語句,而是一個表示式。

JDK 13中switch的多值匹配

當你把switch中的case後的冒號改為箭頭之後,此時switch就不會貫穿了,但在某些情況下,程式本來就希望貫穿比如我就希望兩個case共用一個執行體!JDK 12之後的switch中的case也支援多值匹配,這樣程式就變得更加簡潔了。例如如下程式。

public class Demo04{ public static void main(String[] args) {// 宣告變數score,併為其賦值為‘C’ var score = ‘B’;// 執行switch分支語句 String s = switch (score) { case ‘A’, ‘B’ -> “上等”; case ‘C’ -> “中等”; case ‘D’, ‘E’ -> “下等”; default -> “成績資料輸入非法!”; }; System。out。println(s); }}

JDK 13的Yielding a value

當使用箭頭標籤時,箭頭標籤右邊可以是表示式、throw語句或是程式碼塊。如果是程式碼塊,需要使用yield語句來返回值。下面程式碼中的print方法中的default語句的右邊是一個程式碼塊。在程式碼塊中使用yield來返回值。,JDK 13引入了一個新的yield語句來產生一個值,該值成為封閉的switch表示式的值。

public void print(int days) { // 宣告變數score,併為其賦值為‘C’ var score = ‘B’; String result = switch (score) { case ‘A’, ‘B’ -> “上等”; case ‘C’ -> “中等”; case ‘D’, ‘E’ -> “下等”; default -> { if (score > 100) { yield “資料不能超過100”; } else { yield score + “此分數低於0分”; } } }; System。out。println(result);}

​ 在switch表示式中不能使用break。switch表示式的每個標籤都必須產生一個值,或者丟擲異常。switch表示式必須窮盡所有可能的值。這意味著通常需要一個default語句。一個例外是列舉型別。如果窮盡了列舉型別的所有可能值,則不需要使用default。在這種情況下,編譯器會自動生成一個default語句。這是因為列舉型別中的列舉值可能發生變化。比如,列舉型別Color 中原來只有3個值:RED、GREEN和BLUE。使用該列舉型別的switch表示式窮盡了3種情況並完成編譯。之後Color中增加了一個新的值YELLOW,當用這個新的值呼叫之前的程式碼時,由於不能匹配已有的值,編譯器產生的default會被呼叫,告知列舉型別發生改變

小結

從以上案例可以看出JDK 12到JDK 13對switch的功能做了很大的改進,程式碼也十分的簡化,目前來看switch依然是不支援區間匹配的,未來是否可以支援,我們拭目以待。

2。2 JEP 355 文字塊升級(預覽)

引入

在Java中,在字串文字中嵌入HTML,XML,SQL或JSON片段“。。。”通常需要先進行轉義和串聯的大量編輯,然後才能編譯包含該片段的程式碼。該程式碼段通常難以閱讀且難以維護,因此,如果具有一種語言學機制,可以比多行文字更直觀地表示字串,而且可以跨越多行,而且不會出現轉義的視覺混亂,那麼這將提高廣泛Java類程式的可讀性和可寫性。從JDK 13到JDK 13開始文字塊新特性的提出,提高了Java程式書寫大段字串文字的可讀性和方便性。

HTML示例

使用“一維”字串文字*

String html = “\n” + “ \n” + “

Hello, world

\n” + “ \n” + “\n”;

使用“二維”文字塊

String html = “”“

Hello, world

”“”; System。out。println(“”“ Hello, itheima text blocks! ”“”);

文字塊是Java語言的新語法,可以用來表示任何字串,具有更高的表達能力和更少的複雜度。文字塊的開頭定界符是由三個雙引號

"""

開始,從新的一行開始字串的內容。這裡的新起的這行不屬於字串,只表示內容開始,是語法的一部分。以

"""

結束。

"""

可以緊跟字串內容,也可以另起一行。另起一行時,字串內容最後會留有新的一行。

“”“line 1line 2line 3”“”

等效於字串文字:

“line 1\nline 2\nline 3\n”

或字串文字的串聯:

“line 1\n” +“line 2\n” +“line 3\n”

如果在字串的末尾不需要行終止符,則可以將結束定界符放在內容的最後一行。例如,文字塊:

“”“line 1line 2line 3”“”

等效於字串文字:

“line 1\nline 2\nline 3”

文字塊可以表示空字串,儘管不建議這樣做,因為它需要兩行原始碼:

String empty = “”“”“”;

String a = “”“”“”; // no line terminator after opening delimiterString b = “”“ ”“”; // no line terminator after opening delimiterString c = “”“ ”; // no closing delimiter (text block continues to EOF)String d = “”“ abc \ def ”“”; // unescaped backslash (see below for escape processing)

HTML

使用原始字串語法:

String html = “\n” + “ \n” + “

Hello, world

\n” + “ \n” + “\n”;

使用文字塊文字塊語法:

String html = “”“

Hello, world

”“”;

SQL

使用原始的字串語法:

String query = “SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`\n” + “WHERE `CITY` = ‘INDIANAPOLIS’\n” + “ORDER BY `EMP_ID`, `LAST_NAME`;\n”;

使用文字塊語法:

String query = “”“ SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB` WHERE `CITY` = ‘INDIANAPOLIS’ ORDER BY `EMP_ID`, `LAST_NAME`; ”“”;

多語言示例

使用原始的字串語法:

ScriptEngine engine = new ScriptEngineManager()。getEngineByName(“js”);Object obj = engine。eval(“function hello() {\n” + “ print(‘\”Hello, world\“’);\n” + “}\n” + “\n” + “hello();\n”);

使用文字塊語法:

ScriptEngine engine = new ScriptEngineManager()。getEngineByName(“js”);Object obj = engine。eval(“”“ function hello() { print(‘”Hello, world“’); } hello(); ”“”);

縮排

java編譯器會自動刪除不需要的縮排:

每行結尾的空格都會刪除

每行開始的共有的空格會自動刪除

只保留相對縮排。

System。out。println(“”“ Hello, itheima text blocks! ”“”);// 結果// > Hello,// > itheima// > text blocks!// >System。out。println(“”“ Hello, itheima text blocks! ”“”);// 結果// > Hello,// > itheima// > text blocks!// >

新行

"""

結束時,將

"""

向左調整,則可以給所有行前加相應數量的空格。將

"""

向右調整,沒有作用。

System。out。println(“”“ Hello, multiline text blocks! ”“”);// 結果// > Hello,// > multiline// > text blocks!

2。3 JEP 350 動態類資料共享歸檔

作用:允許在Java應用程式執行結束時動態歸檔類。歸檔的類將包括預設基層CDS歸檔中不存在的所有已載入應用程式類和庫類。

CDS,是java 12的特性了,可以讓不同 Java 程序之間共享一份類元資料,減少記憶體佔用,它還能加快應用的啟動速度。而JDK13的這個特性支援在Java application執行之後進行動態archive。存檔類將包括預設的基礎層CDS存檔中不存在的所有已載入的應用程式和庫類。也就是說,在Java 13中再使用AppCDS的時候,就不再需要這麼複雜了。該提案處於目標階段,旨在提高AppCDS的可用性,並消除使用者進行試執行以建立每個應用程式的類列表的需要。

目標

JDK13這次對CDS增強的主要目的

改善AppCDS的可用性,減少使用者每次都要建立一個類列表的需要

透過開啟,

-Xshare:dump

選項來開啟靜態歸檔,使用類列表仍然行得通。會包含內建的類載入資訊和使用者定義的類載入資訊

意義

在JDK13中做的增強,可以只開啟命令列選項完成上面過程,在程式執行的時候,動態評估那些類需要歸檔,同時支援內建的類載入器和使用者定義的類載入器。

在第一次程式執行完成之後,會自動的將類進行歸檔,後續在啟動專案的時候也無需指定要使用哪些歸檔,整個過程看起來更加的透明。

2。4 JEP 351 ZGC 增強: ZGC 釋放未使用記憶體

目標

作用:將未使用的堆記憶體還給系統(即未提交的記憶體空間)

詳解

ZGC 是 Java 11 中引入的最為矚目的垃圾回收特性,是一種可伸縮、低延遲的垃圾收集器,不過在 Java 11 中是實驗性的引入,主要用來改善 GC 停頓時間,並支援幾百 MB 至幾個 TB 級別大小的堆,並且應用吞吐能力下降不會超過 15%,目前只支援 Linux/x64 位平臺的這樣一種新型垃圾收集器。

透過在實際中的使用,發現 ZGC 收集器中並沒有像 Hotspot 中的 G1 和 Shenandoah 垃圾收集器一樣,能夠主動將未使用的記憶體釋放給作業系統的功能。對於大多數應用程式來說,CPU 和記憶體都屬於有限的緊缺資源,特別是現在使用的雲上或者虛擬化環境中。如果應用程式中的記憶體長期處於空閒狀態,並且還不能釋放給作業系統,這樣會導致其他需要記憶體的應用無法分配到需要的記憶體,而這邊應用分配的記憶體還處於空閒狀態,處於“忙的太忙,閒的太閒”的非公平狀態,並且也容易導致基於虛擬化的環境中,因為這些實際並未使用的資源而多付費的情況。由此可見,將未使用記憶體釋放給系統主記憶體是一項非常有用且亟需的功能。

Java 13 中對 ZGC 的改進,主要體現在下面幾點:

釋放未使用記憶體給作業系統

支援最大堆大小為 16TB

Java 13 中,ZGC 記憶體釋放功能,預設情況下是開啟的,不過可以使用引數:-XX:-ZUncommit 顯式關閉。

2。5 JEP 353 重新實現舊版Socket API

引入

現在已有的 java。net。Socket 和 java。net。ServerSocket 以及它們的實現類,都可以回溯到 JDK 1。0 時代了。原始socket的維護和除錯都很痛苦。實現類還使用了執行緒棧作為 I/O 的緩衝,導致在某些情況下還需要增加執行緒棧的大小。該實現還存在幾個併發問題,需要徹底解決。在未來的網路世界,要快速響應,不能阻塞本地方法執行緒,當前的實現不適合使用了。

詳解

新的實現類

在 Java 13 之前,透過使用 PlainSocketImpl 作為 SocketImpl 的具體實現。

Java 13 中的新底層實現,引入 NioSocketImpl 的實現用以替換 SocketImpl 的 PlainSocketImpl 實現,此實現與 NIO(新 I/O)實現共享相同的內部基礎結構,並且與現有的緩衝區快取記憶體機制整合在一起,因此不需要使用執行緒堆疊。除了這些更改之外,還有其他一些更便利的更改,如使用 java。lang。ref。Cleaner 機制來關閉套接字(如果 SocketImpl 實現在尚未關閉的套接字上被進行了垃圾收集),以及在輪詢時套接字處於非阻塞模式時處理超時操作等方面。

全新實現的 NioSocketImpl 來替換JDK1。0的PlainSocketImpl。

它便於維護和除錯,與 NewI/O (NIO) 使用相同的 JDK 內部結構,因此不需要使用系統原生代碼。

它與現有的緩衝區快取機制整合在一起,這樣就不需要為 I/O 使用執行緒棧。

它使用 java。util。concurrent 鎖,而不是 synchronized 同步方法,增強了併發能力。

新的實現是Java 13中的預設實現,但是舊的實現還沒有刪除,可以透過設定系統屬性 jdk。net。usePlainSocketImpl來切換到舊版本。

程式碼說明

執行一個例項化Socket和ServerSocket的類將顯示這個除錯輸出。這是預設的(新的)。

Module java。basePackage java。netClass SocketImplpublic abstract class SocketImpl implements SocketOptions { private static final boolean USE_PLAINSOCKETIMPL = usePlainSocketImpl(); private static boolean usePlainSocketImpl() { PrivilegedAction pa = () ->NetProperties。get(“jdk。net。usePlainSocketImpl”); String s = AccessController。doPrivileged(pa); return (s != null) && !s。equalsIgnoreCase(“false”); } /**Creates an instance of platform‘s SocketImpl*/ @SuppressWarnings(“unchecked”)static ScreatePlatformSocketImpl(boolean server) { if (USE_PLAINSOCKETIMPL) { return (S) new PlainSocketImpl(server); } else { return (S) new NioSocketImpl(server); } }}

SocketImpl的USE_PLAINSOCKETIMPL取決於usePlainSocketImpl方法,而它會從NetProperties讀取 dk。net。usePlainSocketImpl配置,如果不為null且不為false,則usePlainSocketImpl方法返回true; createPlatformSocketImpl會根據USE_PLAINSOCKETIMPL來建立PlainSocketImpl或者NioSocketImpl。

透過這些更改,Java Socket API 將更易於維護,更好地維護將使套接字程式碼的可靠性得到改善。同時 NIO 實現也可以在基礎層面完成,從而保持 Socket 和 ServerSocket 類層面上的不變。

2。6 其他特性

上面列出的是大方面的特性,除此之外還有一些api的更新及廢棄,主要見 JDK 13 Release Notes,這裡舉幾個例 子。 https://jdk。java。net/13/release-notes

增加項

新增FileSystems。newFileSystem(Path, Map) Method 新的java。nio。ByteBuffer Bulk get/put Methods Transfer Bytes Without Regard to Buffer Position 支援Unicode 12。1 新增-XX:SoftMaxHeapSize Flag,目前僅僅對ZGC起作用 ZGC的最大heap大小增大到16TB

移除項

移除awt。toolkit System Property 移除Runtime Trace Methods 移除-XX:+AggressiveOpts 移除Two Comodo Root CA Certificates、Two DocuSign Root CA Certificates 移除內部的com。sun。net。ssl包

廢棄項

廢棄-Xverify:none及-noverify 廢棄rmic Tool並準備移除 廢棄javax。security。cert並準備移除

已知問題

不再支援Windows 2019 Core Server 使用ZIP File System (zipfs) Provider來更新包含Uncompressed Entries的ZIP或JAR可能造成檔案損壞

展望

Java 在更新發布週期為每半年釋出一次之後,在合併關鍵特性、快速得到開發者反饋等方面,做得越來越好。從 Java 11 到 Java 13,目前確實是嚴格保持半年更新的節奏。Java 13 版本的釋出帶來了些新特性和功能增強、效能提升和改進嘗試。

以上包含的5個特性,能夠改變開發者的編碼風格的主要有Text Blocks和Switch Expressions兩個新特性,但是這兩個特性還處於預覽階段。

而且,JDK13並不是LTS(長期支援)版本,如果你正在使用Java 8(LTS)或者Java 11(LTS),暫時可以不必升級到Java 13。

最後,祝大家早日學有所成,拿到滿意offer,快速升職加薪,走上人生巔峰。

可以的話請給我一個三連支援一下我喲