Java半年就會更新一次新特性,再不掌握就要落伍了:Java15 的新特性

      網友投稿 838 2022-05-30

      你好,我是看山。

      本文收錄在 《從小工到專家的 Java 進階之旅》 系列專欄中。

      從 2017 年開始,Java 版本更新策略從原來的每兩年一個新版本,改為每六個月一個新版本,以快速驗證新特性,推動 Java 的發展。從 《JVM Ecosystem Report 2021》 中可以看出,目前開發環境中有近半的環境使用 Java8,有近半的人轉移到了 Java11,隨著 Java17 的發布,相信比例會有所變化。

      因此,準備出一個系列,配合示例講解,闡述各個版本的新特性。

      概述

      Java15 是在 2020 年 9 月發布的一個短期版本,新增特性如下:

      JEP 339:Edwards-Curve 數字簽名算法

      JEP 360:密封的類和接口(預覽功能)

      JEP 371:隱藏類

      JEP 372:移除 Nashorn JavaScript 引擎

      JEP 373:重新實現 DatagramSocket 接口

      JEP 374:禁用偏向鎖

      JEP 375:instanceof 匹配模式(第二版預覽功能)

      JEP 377:ZGC:可伸縮低延遲垃圾收集器

      JEP 378:文本塊

      JEP 379:Shenandoah:低暫停時間垃圾收集器

      JEP 381:移除 Solaris 和 SPARC 端口 API

      JEP 383:外部存儲器訪問 API(第二版孵化功能)

      JEP 384:Record 類型(第二版預覽功能)

      JEP 385:廢除 RMI Activation

      接下來我們一起看看這些特性。

      Edwards-Curve 數字簽名算法(JEP 339)

      Edwards-Curve 數字簽名算法(EdDSA),一種根據 RFC 8032 規范所描述的 Edwards-Curve 數字簽名算法(EdDSA)實現加密簽名。

      EdDSA 是一種現代的橢圓曲線方案,與 JDK 中的現有簽名方案相比,EdDSA 具有更高的安全性和性能,因此備受關注。它已經在 OpenSSL 和 BoringSSL 等加密庫中得到支持,目前在區塊鏈領域用的比較多。

      我們看下官方給的例子:

      byte[] msg = "Hello, World!".getBytes(StandardCharsets.UTF_8); // example: generate a key pair and sign KeyPairGenerator kpg = KeyPairGenerator.getInstance("Ed25519"); KeyPair kp = kpg.generateKeyPair(); // algorithm is pure Ed25519 Signature sig = Signature.getInstance("Ed25519"); sig.initSign(kp.getPrivate()); sig.update(msg); System.out.println(Hex.encodeHexString(sig.sign())); // example: use KeyFactory to contruct a public key KeyFactory kf = KeyFactory.getInstance("EdDSA"); NamedParameterSpec paramSpec = new NamedParameterSpec("Ed25519"); EdECPublicKeySpec pubSpec = new EdECPublicKeySpec(paramSpec, new EdECPoint(true, new BigInteger("1"))); PublicKey pubKey = kf.generatePublic(pubSpec); System.out.println(pubKey.getAlgorithm()); System.out.println(Hex.encodeHexString(pubKey.getEncoded())); System.out.println(pubKey.getFormat());

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      例子中 Ed25519 是使用 SHA-512(SHA-2)和 Curve25519 的 EdDSA 簽名方案。旨在提供與高質量 128 位對稱密碼相當的抗攻擊能力,公鑰長度為 256 位,簽名長度為 512 位。

      隱藏類(JEP 371)

      Java15 引入了一個新的特性:隱藏類(Hidden Classes),一個專為框架而設計的特性。大多數開發人員不會直接使用這個特性,一般是通過動態字節碼或 JVM 語言來使用隱藏類。

      隱藏類有下面三個特點:

      不可發現:在運行時生成內部類對象;

      訪問控制:只能通過反射訪問,不能直接被其他字節碼訪問;

      較短的生命周期:可獨立于其他類加載、卸載,且效率很高,能夠減少框架的內存占用。

      隱藏類的功能特性還是比較有意思的,會涉及類加載、卸載、不可見、反射等很多內容,后續會開文單獨聊,文章會放在 從小工到專家的 Java 進階之旅 專欄中。

      重新實現 DatagramSocket 接口(JEP 373)

      老的 DatagramSocket API 在 Java15 中被重寫,是繼 Java14 重寫 Socket API 的后續不走。這個特性是 Loom 項目的先決條件。

      目前,DatagramSocket和MulticastSocket將所有的套接字委托為java.net.DatagramSocketImpl的實現,根據不同的平臺,Unix 平臺使用PlainDatagramSocketImpl,Windows 平臺使用TwoStackPlainDatagramSocketImpl和DualPlainDatagramSocketImpl。抽象類DatagramSocketImpl是 Java1.1 提供的,功能很少且有一些過時方法,阻礙了 NOI 的實現。

      類似于 Java14 中對 Socket API 的重寫(參見 Java14 新特性),會在DatagramSocket內部封裝一個DatagramSocket實例,將所有調用直接委托給該實例。包裝實例或者使用 NIO 的DatagramChannel::socket創建套接字,或者是使用原始DatagramSocket類的實現DatagramSocketImpl實現功能(用于實現向后兼容)。

      我們可以看下新的依賴圖:

      禁用偏向鎖(JEP 374)

      在 Java15 中,默認禁用偏向鎖,棄用了所有相關命令行選項。

      偏向鎖是 HotSpot 中一種用于減少非競爭鎖定開銷的優化技術,不過在如今的應用程序中,優化增益不太明顯了。

      根據官方說法,使用偏向鎖增益最多的是大量使用早期同步組件(比如Hashtable、Vector等),隨著新的 API 實現和針對多線程場景引入的支持并發的數據結構,偏向鎖的鎖定及撤銷,會帶來性能的開銷,從而是優化收益降低。

      而且隨著越來越多的功能特性引入,偏向鎖在同步子系統中引入的大量代碼,侵入 HotSpot 其他組件,帶來代碼的復雜性和維護成本,成為代碼優化的阻礙。所以官方要將其移除。

      不過,有些應用在禁用偏向鎖后會出現性能下降,可以使用-XX:+UseBiasedLocking手動開啟。

      ZGC:可伸縮低延遲垃圾收集器(JEP 377)

      ZGC 是在 Java11 引入的(參見 Java11 新特性),一直處于試驗階段,想要體驗,需要在參數中使用-XX:+UnlockExperimentalVMOptions -XX:+UseZGC組合啟用,在 Java15 中,ZGC 成為正式特性,想要使用可以直接用命令-XX:+UseZGC就行。

      ZGC 是一個重新設計的并發的垃圾回收器,可以極大的提升 GC 的性能,支持任意堆大小而保持穩定的低延遲。從 https://openjdk.java.net/jeps/333 給出的數據可以看出來,在 128G 堆大小的測試中,ZGC 優勢明顯,找了一張網上的圖片:

      雖然 ZGC 愿景很好,但是還有很長的路要走,所以默認的垃圾收集器還是 G1。

      Shenandoah:低暫停時間垃圾收集器(JEP 379)

      Shenandoah 是在 Java12 引入的(參見)Java12 的新特性,本次和 ZGC 一起轉正。同樣的,想要使用 Shenandoah,不再需要參數-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC組合,只使用-XX:+UseShenandoahGC即可。需要注意的是,Shenandoah 只在 OpenJDK 中提供,OracleJDK 中并不包含。

      文本塊(JEP 378)

      文本塊是千呼萬喚終于轉正,在 Java13 中首次引入(參見 Java13 的新特性),在 Java14 中又增加了預覽特性(參見 Java14 的新特性),終于在 Java15 確定下來,可以放心使用了。

      我們再復習一下:

      @Test void testTextBlock() { final String singleLine = "你好,我是看山,公眾號「看山的小屋」。這行沒有換行,而且我的后面多了一個空格 \n 這次換行了"; final String textBlockSingleLine = """ 你好,我是看山,公眾號「看山的小屋」。\ 這行沒有換行,而且我的后面多了一個空格、s 這次換行了"""; Assertions.assertEquals(singleLine, textBlockSingleLine); }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      這個功能特性是代碼可讀性的優化。

      預覽

      密封類和接口(JEP 360)

      目前,Java 沒有提供對繼承的細粒度控制,只有 public、protected、private、包內控制四種非常粗粒度的控制方式。

      為此,密封類的目標是允許單個類聲明哪些類型可以用作其子類型。這也適用于接口,并確定哪些類型可以實現它們。該功能特性新增了sealed和non-sealed修飾符和permits關鍵字。

      我們可以做如下定義:

      public sealed class Person permits Student, Worker, Teacher {} public sealed class Student extends Person permits Pupil, JuniorSchoolStudent, HighSchoolStudent, CollegeStudent, GraduateStudent {} public final class Pupil extends Student {} public non-sealed class Worker extends Person {} public class OtherClass extends Worker {} public final class Teacher extends Person {}

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      我們可以先定義一個sealed修飾的類Person,使用permits指定被繼承的子類,這些子類必須是使用final或sealed或non-sealed修飾的類。其中Student是使用sealed修飾,所以也需要使用permits指定被繼承的子類。Worker類使用non-sealed修飾,成為普通類,其他類都可以繼承它。Teacher使用final修飾,不可再被繼承。

      從類圖上看沒有太多區別:

      但是從功能特性上,起到了很好的約束作用,我們可以放心大膽的定義可以公開使用,但又不想被非特定類繼承的類了。

      instanceof 模式匹配-預覽第二版(JEP 375)

      instanceof 模式匹配首先在 Java14 中提供預覽功能(參見 Java14 特性),可以提供instanceof更加簡潔高效的實現,在 Java15 中沒有新增特性,主要是為了再次收集反饋,根據結果看,大家還是很期待這個功能,在 Java16 中正式提供。

      我們再簡單看下instanceof的改進:

      @Test void test1() { final Object obj1 = "Hello, World!"; int result = 0; if (obj1 instanceof String str) { result = str.length(); } else if (obj1 instanceof Number num) { result = num.intValue(); } Assertions.assertEquals(13, result); }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      Record 類型-預覽第二版(JEP 384)

      Record 類型用來增強 Java 語言特性,充當不可變數據載體。在 Java14 中提供預覽功能(參見 Java14 新特性),在 Java15 中提供第二次預覽,這次預覽的目標是收集用戶反饋。

      比如,我們定義一個Person類:

      public record Person(String name, String address) { }

      1

      2

      我們轉換為之前的定義會是一坨下面這種代碼:

      public final class PersonBefore14 { private final String name; private final String address; public PersonBefore14(String name, String address) { this.name = name; this.address = address; } public String name() { return name; } public String address() { return address; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } PersonBefore14 that = (PersonBefore14) o; return Objects.equals(name, that.name) && Objects.equals(address, that.address); } @Override public int hashCode() { return Objects.hash(name, address); } @Override public String toString() { return "PersonBefore14{" + "name='" + name + '\'' + ", address='" + address + '\'' + '}'; } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      Record 類型特性有四個特性:

      設計一個面向對象的結構,表達簡單的信息聚合;

      幫助開發人員專注于建模不可變數據,而不是可擴展的行為;

      自動實現數據驅動的方法,比如equals、getter、setter等方法;

      保留長期存在的 Java 規范,比如遷移兼容性。

      我們不能將 Record 類型簡單的理解為去除“樣板化”代碼的功能,它不是解決 JavaBean 命名約定的中很多模板化方法的冗余繁雜問題,它的目標不是類似 Lombok 等工具自動生成代碼的功能,是從開發人員專注模型的角度出發的。

      孵化

      外部存儲器訪問 API-孵化第二版(JEP 383)

      外部存儲器訪問 API 在 Java14 開始孵化(參見 Java14 新特性),在 Java15 中繼續孵化狀態,這個版本中增加了幾個特性:

      新的VarHandleAPI,用于定制內存訪問句柄;

      支持Spliterator接口實現并行處理內存段;

      增強了對映射內存段的支持;

      能夠像本機調用一樣操作或間接操作內存地址。

      Java 每半年就會更新一次新特性,再不掌握就要落伍了:Java15 的新特性

      外部內存通常是說那些獨立 JVM 之外的內存區域,可以不受 JVM 垃圾收集的影響,通常能夠處理較大的內存。

      這些新的 API 雖然不會直接影響多數的應用類開發人員,但是他們可以在內存的第三方庫中提供支持,包括分布式緩存、非結構化文檔存儲、大型字節緩沖區、內存映射文件等。

      其他

      移除 Nashorn JavaScript 引擎(JEP 372)

      Nashorn JavaScript 引擎最初在 Java8 中引入(參見 Java8 新特性),在 Java11 被標記為過期,在 Java15 中被刪除,包括 Nashorn JavaScript 引擎、API、jjs 工具等內容。

      Nashorn JavaScript 引擎是一個 JavaScript 腳本引擎,用來取代 Rhino 腳本引擎,對 ECMAScript-262 5.1 有完整的支持,增強了 Java 和 JavaScript 的兼容性,而且有很強的性能。

      隨著 GraalVM 和其他虛擬機技術最近的引入,Nashorn 引擎不再在 JDK 生態系統中占有一席之地。而且,ECMAScript 腳本語言結構、API 改變速度太快,Nashorn JavaScript 引擎維護成本太高,所以,直接刪了。

      移除 Solaris 和 SPARC 端口 API(JEP 381)

      Solaris 和 SPARC 都已被 Linux 操作系統和英特爾處理器取代。放棄對 Solaris 和 SPARC 端口的支持將使 OpenJDK 社區的貢獻者能夠加速開發新功能,從而推動平臺向前發展。

      Solaris 和 SPARC 端口 API 在 Java14 中標記過時,在 Java15 中徹底移除。僅僅半年就痛下殺手,可見社區對于維護這些 API 深受折磨。

      廢除 RMI Activation(JEP 385)

      RMI Activation 在 Java15 中標記為廢除,會在未來版本刪除。之所以被刪除,是因為在現代的 web 應用中,已經不需要這種激活機制,繼續維護,增加了 Java 開發人員的維護負擔。在 Java8 的時候,已經將其設置為非必選項。

      從開發系統的角度看,雖然 RMI Activation 是一個還不錯的設計,但是已經有其他替代方案,繼續維護開發下去,成本收益完全不匹配,及早舍棄,可以選擇更加優秀的方案。有些類似于零邊際成本的思想。

      文末總結

      本文介紹了 Java15 新增的特性,完整的特性清單可以從 https://openjdk.java.net/projects/jdk/15/ 查看。后續內容會發布在 從小工到專家的 Java 進階之旅 系列專欄中。

      青山不改,綠水長流,我們下次見。

      推薦閱讀

      一文掌握 Java8 Stream 中 Collectors 的 24 個操作

      一文掌握 Java8 的 Optional 的 6 種操作

      使用 Lambda 表達式實現超強的排序功能

      Java8 的時間庫(1):介紹 Java8 中的時間類及常用 API

      Java8 的時間庫(2):Date 與 LocalDate 或 LocalDateTime 互相轉換

      Java8 的時間庫(3):開始使用 Java8 中的時間類

      Java8 的時間庫(4):檢查日期字符串是否合法

      Java8 的新特性

      Java9 的新特性

      Java10 的新特性

      Java11 中基于嵌套關系的訪問控制優化

      Java11 的新特性

      Java12 的新特性

      Java13 的新特性

      Java14 的新特性

      從小工到專家的 Java 進階之旅

      你好,我是看山。游于碼界,戲享人生。如果文章對您有幫助,請、、關注。我還整理了一些精品學習資料,關注公眾號「看山的小屋」,回復“資料”即可獲得。

      個人主頁:https://www.howardliu.cn

      個人博文:Java 每半年就會更新一次新特性,再不掌握就要落伍了:Java15 的新特性

      CSDN 主頁:https://kanshan.blog.csdn.net/

      CSDN 博文:Java 每半年就會更新一次新特性,再不掌握就要落伍了:Java15 的新特性

      Java JVM

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Android CheckedTextView 使用+實例
      下一篇:校招HTTP面試常見問題匯集(詳解)
      相關文章
      99久久国产亚洲综合精品| 亚洲精品A在线观看| 色噜噜AV亚洲色一区二区| MM1313亚洲精品无码久久| 亚洲一级免费毛片| 亚洲手机中文字幕| 亚洲视频一区二区三区| 久久久久亚洲AV成人片| 夜夜亚洲天天久久| 亚洲自偷自拍另类图片二区| 亚洲最大成人网色| 亚洲视频网站在线观看| 亚洲欧洲日产国码二区首页| 亚洲一区二区三区播放在线| 国产精品亚洲精品| 亚洲日本天堂在线| 亚洲国产欧美日韩精品一区二区三区| 亚洲午夜无码毛片av久久京东热| 亚洲综合无码无在线观看| 亚洲日韩AV一区二区三区中文| 亚洲乱妇老熟女爽到高潮的片| 亚洲日韩精品无码AV海量| 亚洲高清毛片一区二区| 国产成人+综合亚洲+天堂| 亚洲裸男gv网站| 国产精品亚洲一区二区三区在线| 亚洲国产一成人久久精品| 久久久久亚洲av无码尤物| 久久久无码精品亚洲日韩按摩| 亚洲精品国产情侣av在线| 亚洲人成电影青青在线播放| 亚洲av成人一区二区三区| 亚洲日韩精品A∨片无码加勒比| 日本系列1页亚洲系列| 亚洲精品无码日韩国产不卡?V| 亚洲色大成网站WWW久久九九| 久热综合在线亚洲精品| 精品亚洲麻豆1区2区3区| tom影院亚洲国产一区二区| 亚洲欧美日韩中文二区| 免费亚洲视频在线观看|