譯者 | 晶顏
審校 | 重樓
Java的內部系統和語法在不斷發展,這些變化主要是通過Java社區進程(JCP)和Java增強提案(JEPs)來實現的。JCP和JEP共同定義了描述、設計和引入JVM(Java虛擬機)新特性的路徑。它們保持了Java語言和平臺的動態性和社區的參與性。隨著JDK 24發布日期的臨近,現在是時候看看即將到來的JEP是如何完成這一進程的。
JEP進程的各個階段
你可以在OpenJDK主頁上查看JEP索引,獲取所有JEP的目錄,包括過去和現在提交給Java的JEP。概括來說,JEP是根據其發展階段進行組織的:
- 正在運行的JEP(In-flight JEPs)是目前正在研究的提案,將包含在Java的未來版本中。這包括從預覽和可用于實驗的提案到最近被接受用于開發的提案的所有內容。這個集合中的所有提案都已經經過了審查,并且很可能在未來的Java版本中出現。
- 提交的JEP(Submitted JEPs)已經完成了創建過程,現在已經正式提交,但尚未被接受。一旦它們被接受,將進入In-flight階段。
- JEP草案(Draft JEPs)是正在制定的提案,以便進入準備正式提交的狀態。當這種情況發生時,它們將上升到Submitted JEPs狀態。
- 交付的功能、基礎設施和信息性JEP(informational JEPs)都是過去成功的JEP,它們已經成為JVM的一部分。有些甚至已經交付,然后由進一步的JEP進行改進。
- 撤回的JEP(Withdrawn JEPs)是指沒有成功而被撤回的提案。
你可能還會注意到索引開頭的進程JEP(Process JEP)。這些是幫助你理解和定義進程本身的程序性JEP。
有時候,較大的JEP會被分解成多個部分或階段。例如,JEP 462:結構化并發(第二次預覽版)在交付的功能集中有一個單獨的條目。
目前最著名的In-flight JEP
目前有許多有趣的JEP正在開發中。下述所強調的主要是旨在調優和重構JVM以及擴展和增強語言的提案。
JEP 485:流收集器
流收集器(Stream Gatherers)使函數操作更具可定制性。流收集器API公開了一個稱為收集器的低級操作符接口,開發人員可以使用收集器對流進行以前很難或不可能的操作,比如處理同構集合類型。
JEP 485提案是先前兩輪預覽——在JDK 23中交付的JEP 473以及在JDK 22中交付的JEP 461的更新版。該功能旨在增強 Stream API,使其能夠支持自定義中間操作,讓流式管道能夠以一種不易通過現有內置中間操作實現的方式轉換數據。
流收集器雖非每天都需要的功能,但當你需要它的時候,它還是很棒的。它把一個令人沮喪的邊緣情況變成了一個簡單的解決方案。
JEP 484:類文件API
類文件(Class-File)API針對的是庫和框架開發人員,他們需要用額外的功能修飾Java程序的編譯輸出。這是Java中一個長期存在的方法。Java生態系統中有許多用于此類開發的工具,但是JDK的快速變化使得采用更加標準化的方法變得非常重要。
類文件API是用于解析、操作和輸出框架或庫的“.class”結構的標準機制。然后,其他開發人員工具(以及JDK本身)便可以在提供的輸出上進行構建。
JEP 478:密鑰派生函數API(預覽)
JEP 478改進并擴展了Java處理密鑰和哈希等加密元素的原生能力。它旨在使這些操作更加強大,包括前瞻性能力,以幫助抵御未來的量子計算攻擊。
涉及密碼學的開發人員將使用密鑰派生函數(Key Derivation Function)API來處理諸如使用Argon2等高級算法的散列密碼之類的事情。JEP 478升級了Java的內置加密支持,并為未來幾年提供了更好的定位。
JEP 478目前是一個預覽提案,這意味著它在成為官方功能之前可能還有一段路要走。
JEP 472:準備限制對JNI的使用
作為巴拿馬項目(Project Panama)用外部函數內存API取代JNI的一部分,JEP 472表明JVM正在棄用Java本機接口。這個提案提醒了應用程序開發人員,JNI將在默認情況下受到限制。這個JEP關注的是使JNI和FFM API更加一致和安全。使用JNI或FFM的開發人員將受到此更改的影響,因為它要求顯式啟用這些特性,如果未啟用則會發出警告。
JEP 468:派生記錄創建(預覽)
JEP 468提案通過派生創建記錄來增強Java語言。由于記錄是不可變的對象,開發人員經常會根據舊記錄創建新記錄,以建立新數據模型。派生創建可從現有記錄派生出新記錄,只需指定不同的組件即可,從而簡化代碼編寫。
該提案的作者提供了一個例子,將現有的Point實例(nextLoc)在新的finalLoc實例中進行擴展:
Point finalLoc = nextLoc with {
x *= 2;
y *= 2;
z *= 2;
};
本例中的Point類引用一個三維整數記錄。這消除了向Point類添加鏈接方法的需要。下面是使用鏈接法的例子:
Point finalLoc = nextLoc
with { x *= 2; }
with { y *= 2; }
with { z *= 2; };
總的來說,JEP是對記錄功能的一個很好的補充。
JEP 198:輕量級JSON API
JEP 198中提出的功能備受開發人員青睞。處理JSON是現代編程中無法繞過的一個事實,它無處不在,而且有很好的存在理由。在JavaScript中使用JSON非常容易,而在Java中則需要第三方庫。有時,這些API并不容易使用。
不幸的是,JEP 198起源于2014年,但自2017年以來一直沒有更新。這是一個有價值的JEP例子,它處于運行狀態,但卻并非得到有效改進。希望未來能有更積極的發展。
JEP 479:移除Windows 32位x86端口
JDK 21已通過JEP 479完成了棄用32位Windows的工作。一旦該提案成為Java的一部分,Java平臺將不再支持32位窗口。JEP描述了刪除這些代碼路徑將如何簡化JVM。
JEP 218:原始類型上的泛型
Java 泛型的早期妥協之一是泛型的類型變量只能用引用類型實例化,而不能使用原始類型。這既不方便(當想使用 List<int> 時只能用 List<Integer>),又很昂貴(裝箱有性能開銷)。
作為Valhalla項目的一部分,JEP 218是在泛型中使用原始類型的能力。這是對基本Java語法的重大改進,意味著大量的內部規劃和重構。統一泛型和原語意味著我們擺脫了原語包裝和(自動)裝箱。這為徹底統一原語和對象以及引入值類型掃清了道路,且將是很長一段時間以來我們編寫Java方式的最大變化。
JEP 483:提前類加載和鏈接
JEP 483是JVM團隊致力于改進Java底層行為的一個很好的例子。最終的結果是一個更好的平臺:一個啟動和重新加載更快的平臺。
總體思路是,JVM增加了快速加載類的方法,同時保留了其他領域的動態,從而加快了啟動和預熱時間。應用程序開發人員不需要做任何特別的事情來利用這個特性;在即將發布的HotSpot JVM版本中,我們將能免費獲得它。
JEP 475: G1延遲屏障擴展
與JEP 483一樣,JEP 475也是一種重構,應用程序開發人員不會直接使用它。相反地,它為實現垃圾收集例程的平臺開發人員提高了HotSpot JVM的性能和可訪問性。
該JEP建議將G1垃圾收集器的屏障擴展從C2 JIT編譯器的早期階段推遲到后期階段,以此來簡化G1垃圾收集器屏障的實現。這些屏障記錄了有關應用程序內存訪問的信息。目標是在使用G1收集器時減少C2的執行時間,這對于使Java成為更強大的云平臺至關重要。
JEP 450:壓縮對象頭(實驗)
作為另一個內部性能改進提案,JEP 450旨在減少Java對象在內存中的大小。實際測試表明,對象占用的堆空間大部分是對象頭數據。這意味著,“將每個對象的標頭從96位減少到64位可以把總體堆使用量提高10%以上,因為標頭是每個對象的固定成本。較小的平均對象大小可以改善內存使用、GC壓力和數據局部性。”
這是另一個受歡迎的內部重構,我們可以期待它無聲地改進我們程序的運行方式。
JEP 111:正則表達式的附加Unicode結構
JEP 111擴展了正則表達式可以處理的字符類型,涵蓋了更多的Unicode技術標準。具體來說,它添加了以下可以在字符串中處理的字符類型:
- Unicode名稱屬性:\N \{…\}
- 擴展Grapheme Clusters:\X
- Unicode換行序列,如TR#18 Line Boundaries:\R
- Perl風格的命名捕獲組和捕獲組結構:\g \{…\}
- 更完整的Unicode屬性,如\p \{IsXXXX\}
- 水平/垂直空白符:\h \H \v \V
結語
本文只探討了一些調優和重構JVM以及擴展和增強Java語言的提案,其他還有很多正在運行以及處于草案階段的JEP提案。有興趣的話,可以自行查看索引,以更好地了解Jave系統。
原文標題:12 Java Enhancement Proposals changing Java,作者:Matthew Tyson