日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JDK15真的来了,一起来看看它的新特性

發布時間:2024/2/28 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JDK15真的来了,一起来看看它的新特性 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 簡介
  • JDK15的新特性
    • JEP 385 Deprecate RMI Activation for Removal
    • JEP 371 Hidden Classes
    • JEP 339 Edwards-Curve Digital Signature Algorithm (EdDSA)
    • JEP 375 Pattern Matching for instanceof (Second Preview)
    • JEP 384 Records (Second Preview)
    • JEP 360 Sealed Classes (Preview)
    • JEP 378 Text Blocks
  • 總結

簡介

一年兩次的JDK最新版本JDK15在2020年9月15日正式發布了,這次的JDK15給我們帶了隱藏類,EdDSA,模式匹配,Records,封閉類和Text Block等諸多新特性。

一起來看看吧。

JDK15的新特性

JEP 385 Deprecate RMI Activation for Removal

RMI Activation被標記為Deprecate,將會在未來的版本中刪除。

RMI大家應該都清楚,RMI就是Remote Method Invocation,翻譯成中文就是遠程方法調用,是在JDK1.2中引入的。

RMI為java提供了開發分布式系統的強大能力。而J2EE的規范EJB就是使用RMI來實現的bean的遠程調用的。

在RMI系統中,遠程系統中存在很多分布式對象,如果這些分布式對象一直處于活動狀態的話,將會占用很多寶貴的系統資源。

于是RMI引入了一種lazy Activation的方式,這種方式就叫做延遲激活。

這里有兩個概念,活動對象和被動對象。

活動對象是在某些系統上的JVM中實例化并對外暴露的遠程對象。被動對象是尚未在JVM中實例化(或暴露)但可以進入主動狀態的對象。

將被動對象轉換為主動對象的過程稱為激活。激活要求對象與JVM關聯,這可能會將該對象的類加載到JVM中,并且將該對象恢復為之前的狀態。

在RMI系統中,我們使用延遲激活。延遲激活將激活對象推遲到客戶第一次使用(即第一次方法調用)之前。

既然RMI Activation這么好用,為什么要廢棄呢?

因為對于現代應用程序來說,分布式系統大部分都是基于Web的,web服務器已經解決了穿越防火墻,過濾請求,身份驗證和安全性的問題,并且也提供了很多延遲加載的技術。

所以在現代應用程序中,RMI Activation已經很少被使用到了。并且在各種開源的代碼庫中,也基本上找不到RMI Activation的使用代碼了。

為了減少RMI Activation的維護成本,在JDK8中,RMI Activation被置為可選的。現在在JDK15中,終于可以廢棄了。

JEP 371 Hidden Classes

Hidden Classes是什么呢?

Hidden Classes就是不能直接被其他class的二凈值代碼使用的class。Hidden Classes主要被一些框架用來生成運行時類,但是這些類不是被用來直接使用的,而是通過反射機制來調用。

通常來說基于JVM的很多語言都有動態生成類的機制,這樣可以提高語言的靈活性和效率。

比如在JDK8中引入的lambda表達式,JVM并不會在編譯的時候將lambda表達式轉換成為專門的類,而是在運行時將相應的字節碼動態生成相應的類對象。

另外使用動態代理也可以為某些類生成新的動態類。

那么我們希望這些動態生成的類需要具有什么特性呢?

  • 不可發現性。因為我們是為某些靜態的類動態生成的動態類,所以我們希望把這個動態生成的類看做是靜態類的一部分。所以我們不希望除了該靜態類之外的其他機制發現。

  • 訪問控制。我們希望在訪問控制靜態類的同時,也能控制到動態生成的類。

  • 生命周期。動態生成類的生命周期一般都比較短,我們并不需要將其保存和靜態類的生命周期一致。

  • 但是現有的類的定義API ClassLoader::defineClass和Lookup::defineClass是不管類的字節碼是如何生成的,他們都是平等對待。

    所以我們需要一些API來定義無法發現的且具有有限生命周期的隱藏類。這將提高所有基于JVM的語言實現的效率。

    比如:

    java.lang.reflect.Proxy可以定義隱藏類作為實現代理接口的代理類。

    java.lang.invoke.StringConcatFactory可以生成隱藏類來保存常量連接方法;

    java.lang.invoke.LambdaMetaFactory可以生成隱藏的nestmate類,以容納訪問封閉變量的lambda主體;

    JavaScript引擎可以為從JavaScript程序轉換的字節碼生成隱藏的類,因為當引擎不再使用它們時,這些類將被卸載。

    普通類是通過調用ClassLoader::defineClass創建的,而隱藏類是通過調用Lookup::defineHiddenClass創建的。

    這使JVM從提供的字節中派生一個隱藏類,鏈接該隱藏類,并返回提供對隱藏類的反射訪問的查找對象。

    調用程序可以通過返回的查找對象來獲取隱藏類的Class對象。

    JEP 339 Edwards-Curve Digital Signature Algorithm (EdDSA)

    實現了EdDSA橢圓曲線簽名算法。

    這里就不多講橢圓曲線簽名算法了,如果又想了解的朋友可以給我留言。

    JEP 375 Pattern Matching for instanceof (Second Preview)

    Pattern Matching 就是說可以在做pattern mathching的時候,直接對該對象進行類型的轉換。

    現在這個特性還是預覽版本的。

    我們看一下具體的例子:

    if (obj instanceof String) {String s = (String) obj;// use s }

    在Pattern Matching之前,我們使用instanceof之后,還需要對該對象進行強制類型轉換才能使用。

    但是在Pattern Matching之后,我們可以這樣用:

    if (obj instanceof String s) {// can use s here } else {// can't use s here }

    是不是很方便。

    JEP 384 Records (Second Preview)

    Record是一種輕量級的class,可以看做是數據結構體。和scala中的case有點相似。

    舉個自定義User的例子看一下Record是怎么用的:

    public record Address(String addressName,String city ) { } public record CustUser(String firstName,String lastName,Address address,int age ) {}

    上面我們定義了兩個類,CustUser和Address。CustUser中引用了Address。

    Record和普通的類的區別就在于Record多了一個括號括起來的定義的字段。

    Record類默認是final的,里面的字段默認是private final的。

    要想知道Record到底是怎么工作的,我們可以使用javap來對編譯好的class文件反編譯,運行javap CustUser,可以得到下面的結果:

    警告: 二進制文件CustUser包含com.flydean.records.CustUser Compiled from "CustUser.java" public final class com.flydean.records.CustUser extends java.lang.Record {public com.flydean.records.CustUser(java.lang.String, java.lang.String, com.flydean.records.Address, int);public java.lang.String toString();public final int hashCode();public final boolean equals(java.lang.Object);public java.lang.String firstName();public java.lang.String lastName();public com.flydean.records.Address address();public int age(); }

    上面可以看到final class CustUser繼承自java.lang.Record。

    并且自動添加了默認帶有所有字段的構造函數。各個自動的獲取方法,并實現了toString,hashCode和equals方法。

    天啦,太完美了,我們想要的它居然都有。

    如果上面的javap還不是很清楚的話,大家可以借助IDE的反編譯功能,打開CustUser.class文件看一看:

    public final class CustUser extends java.lang.Record {private final java.lang.String firstName;private final java.lang.String lastName;private final com.flydean.records.Address address;private final int age;public CustUser(java.lang.String firstName, java.lang.String lastName, com.flydean.records.Address address, int age) { /* compiled code */ }public java.lang.String toString() { /* compiled code */ }public final int hashCode() { /* compiled code */ }public final boolean equals(java.lang.Object o) { /* compiled code */ }public java.lang.String firstName() { /* compiled code */ }public java.lang.String lastName() { /* compiled code */ }public com.flydean.records.Address address() { /* compiled code */ }public int age() { /* compiled code */ } }

    注意,上面的反編譯我們可以看到,record中的所有字段都是final的,只能在初始化的時候設置。并且方法里面也沒有提供其他可以改變字段內容的方法。

    所以我們得出了一個震世驚俗的結論:record是immutable的。

    上面的例子中我們只使用了小括號里面的內容,大括號還是空的呀。可不可以像其他正常的類一樣,添加點方法或者構造函數進去呢?

    答案是肯定的。

    先看一個整體的方案:

    public record CustUserWithBody(String firstName,String lastName,Address address,int age ) {public String fullName(){return firstName+ lastName;}public CustUserWithBody{if (age < 18) {throw new IllegalArgumentException( "男大當婚,女大當嫁,18歲未到,不許出嫁!");}} }

    我們在record的主題中,定義了一個方法和一個構造函數。

    先看這個方法,在方法中我們可以訪問到record中定義的變量,但是千萬不要嘗試去修改他們,因為他們是final的,你會得到一個變異錯誤。

    再看這個構造函數,這個構造函數沒有小括號,只有大括號,這種構造函數叫做Compact constructor。你無法在record中定義正常的構造函數,因為會得到一個編譯錯誤。

    在這個Compact constructor中,我們可以對定義的字段進行數據校驗。如上所述。

    JEP 360 Sealed Classes (Preview)

    在Java中,類層次結構通過繼承實現代碼的重用,父類的方法可以被許多子類繼承。

    但是,類層次結構的目的并不總是重用代碼。有時,其目的是對域中存在的各種可能性進行建模,例如圖形庫支持的形狀類型或金融應用程序支持的貸款類型。

    當以這種方式使用類層次結構時,我們可能需要限制子類集從而來簡化建模。

    因為我們引入了sealed class或interfaces,這些class或者interfaces只允許被指定的類或者interface進行擴展和實現。

    舉個例子:

    package com.example.geometry;public abstract sealed class Shapepermits Circle, Rectangle, Square {...}

    上面的例子中,我們指定了Shape只允許被Circle, Rectangle, Square來繼承。

    上面的例子中并沒有指定類的包名,我們可以這樣寫:

    package com.example.geometry;public abstract sealed class Shape permits com.example.polar.Circle,com.example.quad.Rectangle,com.example.quad.simple.Square {...}

    JEP 378 Text Blocks

    Text Blocks是為了解決在java中輸入多行數據的問題。

    比如:

    String html = "<html>\n" +" <body>\n" +" <p>Hello, world</p>\n" +" </body>\n" +"</html>\n";

    可以寫成:

    String html = """<html><body><p>Hello, world</p></body></html>"""; 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";

    非常的方便。

    總結

    好了,JDK15的新特性全都介紹完了。希望大家能夠喜歡。

    本文作者:flydean程序那些事

    本文鏈接:http://www.flydean.com/jdk15-release-new-features/

    本文來源:flydean的博客

    歡迎關注我的公眾號:「程序那些事」最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!

    總結

    以上是生活随笔為你收集整理的JDK15真的来了,一起来看看它的新特性的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。