JDK13到今天已經發布快2個月了,之前有零零散散的試過一些新的特性,但卻沒有整體的整理一下。想到作為Java開發,連使用的JDK(Java Developerment Kit)有什麼特性都不清楚,實在是有些不應該,想要進階為更有價值的JAVA開發人員,一定要跟得上JDK的最新特性。
那再來看下,這份遲來的JDK新特性一覽
JDK13所有的JDK特性都會在JEP進度中提出來和跟蹤:openjdk.java.net/jeps/0
對於每個JDK版本的有什麼特性在對應JDK主頁中檢視:openjdk.java.net/projects/jd…
JDK13主要有5個特性:
350: Dynamic CDS Archives 參考: www.jianshu.com/p/0b8a9d137…351: ZGC: Uncommit Unused Memory 參考:www.jianshu.com/p/18fc5a042…353: Reimplement the Legacy Socket API354: Switch Expressions (Preview)355: Text Blocks (Preview)Dynamic CDS Archives在JDK10中被引入的新特性,但是當時建立步驟比較繁瑣。
# JDK10中需要的步驟1. 需要指定要歸檔那些類 -XX:DumpLoadedClassList=classes.lst2. 建立歸檔 -Xshare:dump -XX:SharedArchiveFile -XX:SharedClassListFile=classes.lst3. 使用歸檔 -Xshare:on -XX:SharedArchiveFile
在JDK13中引入新的選項,在程式退出時自動歸檔:
java -XX:ArchiveClassesAtExit=app.jsa -cp app.jar HelloDemo
使用歸檔步驟與之前相同,預設-Xshare:on是開啟的
類載入過程:
載入->驗證->準備->解析->初始化->使用->解除安裝
載入:找到Class的位置,從Class位置讀取Class檔案內容驗證:檔案格式的驗證、元資料的驗證、位元組碼驗證和符號引用驗證。準備:正式為類變數分配記憶體並設定類變數初始值的階段,這些記憶體都將在方法區中分配。儲存為JDK內部資料結構解析:虛擬機器將常量池中的符號引用轉化為直接引用的過程,解析介面,欄位解析初始化:建立類CDS的設計目的主要為了提升啟動應用時的速度,class-data只需要建立一次,後續重複使用,減少了載入,驗證,準備階段。可能會有解析階段
參考:App CDS實戰
ZGC: Uncommit Unused MemoryZGC從JDK11中被引入進來,在進行GC的時候保證更短的停頓時間,10ms以下,在JDK13中新增了歸還未提交,未使用的記憶體給作業系統
ZGC由許多的ZPage組成,Zpage是不同大小的記憶體區域,分為小、中、大。當ZGC壓縮記憶體時,Zpage被清空到ZPageCache中,ZpageCache是準備隨時被用到的區域,如果被使用,會立刻從ZpageCache中移除到Zpage中,但是如果ZpageCache中的Zpage長時間未使用,則變為未提交使用的記憶體,後續可還給作業系統。
When ZGC compacts the heap, ZPages are freed up and inserted into a page cache, the ZPageCache.
#設定一個時間多久從ZpageCache中移除(evict)Zpage-XX:+UnlockExperimentalVMOptions -XX:+ZUncommit -XX:ZUncommitDelay=<seconds>
參考:ZGC完全指南
Reimplement the Legacy Socket APIJDK底層對Socket的實現非常的古老,從JDK1.0中被使用一直到現在,底層為很早的Java和C程式碼,對於開發JDK的人來說,非常的難以維護和Debug,因此重新實現了Socket API的介面。
JDK13之前,使用PlainSocketImplJDK13引入了,NioSocketImpl替換PlainSocketImpl。來一個HelloWorld案例:
public class HelloApp { public static void main(String[] args) { try (ServerSocket serverSocket = new ServerSocket(8888)) { boolean running = true; System.out.println("listened 8888"); while (running) { Socket clientSocket = serverSocket.accept(); //do something with clientSocket } } catch (IOException e) { e.printStackTrace(); } }}
但是我們仍然可以切換為PlainSocketImpl。需配置jdk.net.usePlainSocketImpl
Switch Expressions (Preview)引入了一個新的關鍵字yield用於返回switch語句的內容。最開始我們寫switch語句都要在語句之前做一些初始化變數,現在可以直接得到swicth語句額返回結果
最開始的switch寫法:
int numLetters;switch (day) { case MONDAY: case FRIDAY: case SUNDAY: numLetters = 6; break; case TUESDAY: numLetters = 7; break; case THURSDAY: case SATURDAY: numLetters = 8; break; case WEDNESDAY: numLetters = 9; break; default: throw new IllegalStateException("Wat: " + day);}
在JDK13中可以這樣寫:
# 沒有邏輯的返回int numLetters = switch (day) { case MONDAY, FRIDAY, SUNDAY -> 6; case TUESDAY -> 7; case THURSDAY, SATURDAY -> 8; case WEDNESDAY -> 9;};# 邏輯較多的處理 String result = switch (number) { case 1, 2: // 邏輯程式碼 yield "one or two"; case 3: // 邏輯程式碼 yield "three"; case 4, 5, 6: yield "four or five or six"; default: yield "unknown"; }; return result;
Text Blocks (Preview)最開始寫長字串的時候,往往要使用多個字串拼接,一是浪費效能,而是看起來很難看。尤其寫HTML字串或者SQL語句時。
// 比如HTMLString html = "<html>\\n" + " <body>\\n" + " <p>Hello, world</p>\\n" + " </body>\\n" + "</html>\\n";
現在可以寫成:
String html = """ <html> <body> <p>Hello, world</p> </body> </html> """;
注意:
其中有個細微的區別,是開頭"""之後必須另起一行,另外結尾的"""是否另起一行有不同的效果注意在使用的時候每一行可能需要處理兩邊的空格"""line 1line 2line 3"""=>"line 1\\nline 2\\nline 3\\n"
"""line 1line 2line 3"""=>"line 1\\nline 2\\nline 3"
最後
JDK13在一定程度上還是可以加快我們的開發速度...,最重要的是其歸檔特性可以大大減少我們應用的啟動時間,ZGC則讓我們在記憶體吃緊時,又帶來了福音。
值得一試!
連結:https://juejin.im/post/5dc4be9cf265da4d31074777