關于JDK15的一些事
點擊上方藍色字體,選擇“標星公眾號”
優(yōu)質(zhì)文章,第一時間送達
? 作者?|? 學海無涯519
來源 |? urlify.cn/EfA7bm
一、為什么要了解JDK15?
2020年9月15日,Oracle官方發(fā)布了JDK15版本,及時關注官方的更新動態(tài),可以讓我們在日常開發(fā)中更合理的選擇更加優(yōu)秀的工具方法,避免使用一些過時的或一些即將被刪除類和方法,保障程序的健壯性、穩(wěn)定性、可移植性。
二、JDK15都為我們帶來了哪些東西?
JEP 339:Edwards-Curve 數(shù)字簽名算法(EdDSA)
JEP 360:密封類(預覽)
JEP 371:隱藏類
JEP 372:刪除Nashorn JavaScript引擎
JEP 373:重新實現(xiàn)舊版DatagramSocket API
JEP 374:禁用和棄用偏置鎖定
JEP 375:instanceof的模式匹配(第二預覽)
JEP 377:ZGC:可擴展的低延遲垃圾收集器
JEP 378:文字塊
JEP 379:Shenandoah:低暫停時間的垃圾收集器
JEP 381:刪除Solaris和SPARC端口
JEP 383:外部存儲器訪問API(第二個孵化器)
JEP 384:Records(第二預覽)
JEP 385:棄用RMI激活以進行刪除
JEP:JDK Enhancement Proposals ,JDK 特性的新增和修改建議。
三、具體說一說JDK15的特性。
1. JEP 339:Edwards-Curve 數(shù)字簽名算法(EdDSA)
官方描述:
EdDSA是一種現(xiàn)代的橢圓曲線簽名方案,與JDK中的現(xiàn)有簽名方案相比,具有多個優(yōu)點。
在相同的安全強度下,開發(fā)比現(xiàn)有的ECDSA實現(xiàn)(使用本機C代碼)更好的性能的EdDSA平臺無關的實現(xiàn)。例如,在安全性?126位時使用Curve25519的EdDSA應該與在安全性?128位時使用曲線secp256r1的ECDSA一樣快。
假設平臺在恒定時間內(nèi)執(zhí)行64位整數(shù)加/乘,請確保時序與秘密無關。另外,該實現(xiàn)將不會基于秘密分支。這些屬性對于防止側(cè)通道攻擊非常有用。
簡而言之:
Edwards-Curve 數(shù)字簽名算法(EdDSA)實現(xiàn)加密簽名功能。且比現(xiàn)有的JDK 中的簽名安全性和性能更高。
2. JEP 360:密封類(預覽)
官方描述:
通過密封的類和接口增強Java編程語言。密封的類和接口限制可以擴展或?qū)崿F(xiàn)它們的其他類或接口。通過將sealed修飾符應用于其聲明來密封類。然后,在anyextends和implements子句之后,該permits子句指定允許擴展密封類的類。
簡而言之:
?限定接口的實現(xiàn)或子類,不是所有的類都能繼承此類或?qū)崿F(xiàn)此類。
注意:
sealed:隱含子類 permits : 許可證
non-sealed:隱含非受限子類
final:隱含無子類
每個允許的子類都只能使用修飾符 final ,sealed和non-sealed中的一個,且三者互斥。
代碼實現(xiàn):
//?創(chuàng)建Person?密封類
public?abstract?sealed?class?Person?permits?Student,?Teacher,?Doctor{
}
//?學生類繼承人類
non-sealed?class?Student?extends?Person{?}
//?老師類繼承人類
final?class?Teacher?extends?Person{?}
//?醫(yī)生類繼承人類
sealed?class?Doctor?extends?Person?permits?OutpDoctor,?InpatDoctor{?}
//?門診醫(yī)生繼承人類
final?class?OutpDoctor?extends?Doctor{?}
//?住院醫(yī)生繼承人類
non-sealed?class?InpatDoctor?extends?Doctor{?}
//?方法類型描述
public?sealed?interface?MethodTypeDesc?permits?DynamicConstantDesc,?MethodTypeDescImpl?{}
//?方法類型描述實現(xiàn)
final?class?MethodTypeDescImpl?implements?MethodTypeDesc?{?}
//?動態(tài)約束描述
non-sealed?class?DynamicConstantDesc?implements?MethodTypeDesc?{}
3. JEP 371:隱藏類
官方描述:
隱藏類是其他類的字節(jié)碼不能直接使用的類。隱藏類適用于在運行時生成類并通過反射間接使用它們的框架。隱藏類可以定義為訪問控制嵌套的成員,并且可以獨立于其他類進行卸載。
簡而言之:
隱藏類的超類型是由類加載器創(chuàng)建的,但隱藏類本身的創(chuàng)建并不涉及任何類加載器。所以可以方便的進行卸載且不用考慮安全問題,并且可以減少程序的內(nèi)存占用。
4. JEP 372:刪除Nashorn JavaScript引擎
官方描述:
隨著ECMAScript語言構(gòu)造以及API的快速適應和修改,我們發(fā)現(xiàn)Nashorn難以維護。官方?jīng)Q定刪除Nashorn JavaScript腳本引擎和API,以及該jjs?工具。
兩個JDK模塊將被永久刪除:
jdk.scripting.nashorn-包含jdk.nashorn.api.scripting和 jdk.nashorn.api.tree軟件包。
jdk.scripting.nashorn.shell-包含jjs工具。
5. JEP 373:重新實現(xiàn)舊版DatagramSocket API(套接字)
官方描述:
用更易于維護和調(diào)試的更簡單,更現(xiàn)代的實現(xiàn)來替換java.net.DatagramSocket和java.net.MulticastSocketAPI的基礎實現(xiàn)。新的實現(xiàn)將很容易適應虛擬線程的工作,當前正在Project Loom中進行探索。
改動原因:
java.net.DatagramSocket和java.net.MulticastSocketAPI的代碼庫及其基礎實現(xiàn)很舊且脆弱:
實現(xiàn)可以追溯到JDK 1.0。它們是傳統(tǒng)Java和C代碼的混合,難以維護和調(diào)試。
的實現(xiàn)
MulticastSocket尤其成問題,因為它可以追溯到IPv6仍處于開發(fā)階段。許多基本的本機實現(xiàn)都嘗試以難以維護的方式協(xié)調(diào)IPv4和IPv6。該實現(xiàn)還存在一些并發(fā)問題(例如,異步關閉),需要進行大修才能正確解決。
此外,在駐留而不是阻塞系統(tǒng)調(diào)用中底層內(nèi)核線程的虛擬線程的情況下,當前實現(xiàn)不適合此目的。隨著基于數(shù)據(jù)報的傳輸再次獲得牽引力(例如?QUIC),需要更簡單,更可維護的實現(xiàn)。
6.JEP 374:禁用和棄用偏置鎖定
官方描述:
在JDK 15之前,始終啟用并提供偏置鎖定。使用此JEP,除非?-XX:+UseBiasedLocking?在命令行上設置,否則在啟動HotSpot時將不再啟用偏置鎖定。
改動原因:
確定是否需要繼續(xù)支持偏向鎖定的傳統(tǒng)同步優(yōu)化,這是維護成本很高的方法。有偏見的鎖定會帶來爭用時需要進行昂貴的撤銷操作的代價。
7.JEP 375:instanceof的模式匹配(第二預覽)
官方描述:
通過為操作員提供模式匹配來增強Java編程語言instanceof。模式匹配使程序中的通用邏輯(即從對象中有條件地提取組件)得以更簡潔,更安全地表示。
簡而言之:
可以使我們的代碼更加簡潔。
代碼示例:
public?static?void?main(String[]?args)?{
????????Object?str?=?"模式匹配";
????????//?模式匹配
????????//?綁定變量s的作用域在&&運算符的右側(cè)以及true塊中、綁定變量s不在||右側(cè)的范圍內(nèi)
//????????if(str?instanceof?String?s?&&?s.length()?>?0?){
????????if(str?instanceof?String?s){
????????????System.out.println(s);
????????}else?{
????????????//?s不能作用于此處
????????//?System.out.printf(s);
????????}
????}
8. JEP 377:ZGC:可擴展的低延遲垃圾收集器(轉(zhuǎn)正)
官方描述:
對ZGC的測試表明它是穩(wěn)定的,并且在撰寫本文時,我們已經(jīng)有幾個月沒有收到針對ZGC的新錯誤了。借助ZGC如今擁有的穩(wěn)定性,功能集和平臺支持,是時候刪除其實驗狀態(tài)并使其成為產(chǎn)品功能了。
今天,可以通過-XX:+UnlockExperimentalVMOptions -XX:+UseZGC命令行選項啟用ZGC 。使ZGC成為產(chǎn)品(非實驗性)功能意味著-XX:+UnlockExperimentalVMOptions不再需要該選件。
該JEP不建議更改默認GC,該默認GC仍為G1。
簡而言之:
ZGC垃圾收集器在JDK15成為正式版,我們可以通過-XX:+UseZGC命令行選項啟用ZGC,但是需要注意的是默認的垃圾收集器仍然是G1。
9. JEP 378:文字塊(轉(zhuǎn)正)
官方描述:
將文本塊添加到Java語言。文本塊是多行字符串文字,它避免了大多數(shù)轉(zhuǎn)義序列的需要,以一種可預測的方式自動設置字符串的格式,并在需要時使開發(fā)人員可以控制格式。
解決了在Java中,在字符串文字中嵌入HTML,XML,SQL或JSON片段"..."通常需要先進行轉(zhuǎn)義和串聯(lián)的大量編輯,然后才能編譯包含該片段的代碼。該代碼段通常難以閱讀且難以維護的問題。
代碼示例:
public?static?void?main(String[]?args)?{
????????String?html?=?"\n"?+
????????????????"????\n"?+
????????????????"????????Hello,?world
\n"?+
????????????????"????\n"?+
????????????????"\n";
????????String?htmlText?=?"""
???????????
???????????????
???????????????????Hello,?world
???????????????
???????????
???????????""";
????????System.out.println("html長度"?+?html.length());
????????System.out.println("htmlText長度"?+?htmlText.length());
????????String?query?=?"SELECT?\"EMP_ID\",?\"LAST_NAME\"?FROM?\"EMPLOYEE_TB\"\n"?+
????????????????"WHERE?\"CITY\"?=?'INDIANAPOLIS'\n"?+
????????????????"ORDER?BY?\"EMP_ID\",?\"LAST_NAME\";\n";
????????String?queryText?=?"""
????????????SELECT?"EMP_ID",?"LAST_NAME"?FROM?"EMPLOYEE_TB"
????????????WHERE?"CITY"?=?'INDIANAPOLIS'
????????????ORDER?BY?"EMP_ID",?"LAST_NAME";
????????????""";
????????System.out.println("query長度"?+?query.length());
????????System.out.println("queryText長度"?+?queryText.length());
????????//?\:取消換行操作
????????//?\s:標識一個空格
????????String?sql1?=?"""
????????????SELECT?id,?name,?age?\
????????????FROM?person\s\
????????????WHERE?id?>?4?\
????????????ORDER?BY?age?DESC
????????????""";
????????String?sql2?=?"SELECT?id,?name,?age?FROM?person?WHERE?id?>?4?ORDER?BY?age?DESC";
????}
錯誤代碼示例:
String?a?=?"""""";???//?no?line?terminator?after?opening?delimiter
String?b?=?"""?""";??//?no?line?terminator?after?opening?delimiter
String?c?=?"""
???????????";????????//?no?closing?delimiter?(text?block?continues?to?EOF)
String?d?=?"""
???????????abc?\?def
???????????""";??????//?unescaped?backslash?(see?below?for?escape?processing)
注意:
文本塊:
"""
line?1
line?2
line?3
"""
等效于字符串文字:
"line?1\nline?2\nline?3\n"
或字符串文字的串聯(lián):
"line?1\n"?+
"line?2\n"?+
"line?3\n"
---------------------------------------------------------
"""
line?1
line?2
line?3"""
等效于字符串文字:
"line?1\nline?2\nline?3"
10. JEP 379:Shenandoah:低暫停時間的垃圾收集器(轉(zhuǎn)正)
官方描述:
將Shenandoah垃圾收集器從實驗功能更改為產(chǎn)品功能。
在JDK 12和更高版本中,通過-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC選項啟用了Shenandoah 。將Shenandoah成為產(chǎn)品功能意味著-XX:+UnlockExperimentalVMOptions不再需要。
簡而言之:
Shenandoah垃圾收集器功能轉(zhuǎn)正,可以通過-XX:+UseShenandoahGC直接使用,Shenandoah 的暫停時間與堆大小無關。
11. JEP 381:刪除Solaris和SPARC端口
官方描述:
刪除所有特定于Solaris操作系統(tǒng)的源代碼。
刪除所有特定于SPARC體系結(jié)構(gòu)的源代碼。
更新文檔和源代碼注釋以用于將來的版本。
改動原因:
當前正在開發(fā)的許多項目和功能(例如Valhalla,Loom和Panama)都需要對CPU體系結(jié)構(gòu)和特定于操作系統(tǒng)的代碼進行重大更改。放棄對Solaris和SPARC端口的支持將使OpenJDK社區(qū)中的貢獻者能夠加速新功能的開發(fā),這些新功能將推動平臺向前發(fā)展。
12.JEP 383:外部存儲器訪問API(第二個孵化器)
官方描述:
引入一個API,以允許Java程序安全有效地訪問Java堆之外的外部內(nèi)存。
在Java 14作為孵化API,在JDK15中第二次孵化。
以jdk.incubator.foreign相同的名稱包形式提供了外部存儲器訪問API ;它引入了三個主要抽象:MemorySegment,MemoryAddress和MemoryLayout。
13.JEP 384:Records(第二預覽)
官方描述:
使用records增強Java編程語言,record 是充當不可變數(shù)據(jù)的透明載體的類。記錄可以看作是名義元組。
設計一個表達簡單值集合的面向?qū)ο蟮臉?gòu)造。
幫助程序員專注于對不可變數(shù)據(jù)進行建模,而不是對可擴展行為進行建模。
自動實現(xiàn)數(shù)據(jù)驅(qū)動的方法,例如
equals和訪問器。保留長期的Java原則,例如標稱類型和遷移兼容性
官方示例:
例如,先前聲明的記錄record Point(int x, int y)?{?}-將被編譯為:
record?Point(int?x,?int?y)?{
????//?Implicitly?declared?fields
????private?final?int?x;
????private?final?int?y;
????//?Other?implicit?declarations?elided?...
????//?Implicitly?declared?canonical?constructor
????Point(int?x,?int?y)?{
????????this.x?=?x;
????????this.y?=?y;
????}
}
簡而言之:
似于lombok,主要目的是為了簡化作用,不用再寫構(gòu)造方法、equals,hashCode,toString等方法。
代碼示例:
public?record?Student(String?name,int?age)?{
}
public?class?Main?{
????public?static?void?main(String[]?args)?{
????????Student?student?=?new?Student("張三",20);
????????System.out.println(student);
????????System.out.println(student.name());
????????System.out.println(student.age());
????}
}
14.JEP 385:棄用RMI激活以進行刪除
官方描述:
棄用RMI激活?機制以便將來刪除。RMI激活是RMI的過時部分,自Java 8開始,RMI激活是可選的。不會棄用RMI的其他部分。
改動原因:
分布式系統(tǒng)至少在過去十年中一直基于Web技術。Web服務領域已經(jīng)解決了有關穿越防火墻,篩選請求,身份驗證和安全性的問題。延遲實例化資源由負載平衡器,業(yè)務流程和容器處理。這些機制在分布式系統(tǒng)的RMI激活模型中均不存在。
RMI激活的使用量幾乎消失了。沒有證據(jù)表明有任何新的應用程序被編寫為使用RMI激活,并且有證據(jù)表明很少有現(xiàn)有應用程序使用RMI激活。對各種開放源代碼庫的搜索幾乎沒有發(fā)現(xiàn)任何與激活相關的API。
間而言之:
RMI激活的功能使用極少,Web服務有更優(yōu)秀的問題解決方案,RMI激活增加了維護的費用。
四、總結(jié)
總的來說,JDK15新功能不多,可以根據(jù)自己的實際需要,根據(jù)JDK版本功能走向來選擇合理的功能。
粉絲福利:Java從入門到入土學習路線圖
??????

??長按上方微信二維碼?2 秒
感謝點贊支持下哈?
