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 各版本支援週期
為了更快地迭代,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。
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%。
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/
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 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
移除項
移除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,快速升職加薪,走上人生巔峰。
可以的話請給我一個三連支援一下我喲