大約是五年前,我寫了一篇文章,概述了其餘語言的一些特性思想,我認爲這些思想可能會對 Java 有好處。從那之後發生了不少事情:那時,Java 8 是最新的發佈版本,而如今,最新的版本是 Java 14。程序員
讓咱們依次查看下每一個特性,看看它的當前狀態是什麼:它是已經被添加到 Java 中了,仍是正在開發中,亦或是當前尚沒有將其歸入 Java 的計劃。編程
我最初的預測排除了具體化泛型(reified generics)。我沒有預見到 Valhalla 項目對從頭開始重構 JVM 的雄心壯志。數組
Valhalla 項目的主要目標是:機器學習
在此描述中隱藏的是已加載的單詞「values」,它已經演變成咱們今天稱之爲內聯類的特性。編程語言
所以,具體化泛型和原語專業化已經被包含到一個更大的項目中了,該項目承諾從根本上改變 Java 的編寫和執行方式。佈局
儘管正在進行深層次的底層變動,但項目團隊的目標包括最大程度地減小對現有 Java 應用程序的破壞,併爲在本身的代碼中使用 Valhalla 功能的開發人員提供一種簡單的、可選的方法。性能
咱們應該注意到,Valhalla 在很大程度上仍然是一項正在進行的項目,並且尚無關於其什麼時候交付的正式路線圖。學習
判決:正在進行中(做爲 Valhalla 項目的一部分)線程
在 Java 的歷史上已經反覆討論過支持該特性的可能性了,可是引入該特性的過程涉及到了許多複雜性。設計
例如,有這樣一個問題,即在 Java 類型系統中如何表示有符號性,以及它是否應該在 JVM 字節碼級別上可見。
這些問題還沒有達成任何使人滿意的共識,所以,Java 仍然不包含無符號算術,而 Valhalla 項目的一個顯著方面是:它不包含對無符號算術的支持。
判決:尚不予考慮
Java 數組的大小受到其設計的一個簡單事實的限制:它們是以 int 做爲索引的。這意味着一個數組被限制爲 2^31 個元素(記住 int 是有符號的),即大約 20 億個條目。
正如最初所設想的那樣,使用 long 而不是 int 的想法將能容許開發人員建立和操縱更大的數組。然而,自從發表最初的「缺失特性」一文以來,社區在此領域的關注點已經轉移到提供對堆外存儲的大型數組的便捷訪問上了。
形成這種狀況的緣由有不少。易於與非 Java 庫(包括機器學習和其餘大量的應用程序)進行互操做是一個重要緣由。然而,大型的堆數組到底有多大用處,這也是一個問題。在進出 Java 堆時,龐大的、具備多個千兆位的數組將會產生巨大的複製成本,並可能會給 JVM 的垃圾收集器形成嚴重的困擾。
因爲這些緣由,在堆外支持的背景下,纔會考慮大型數組,而且該概念已被歸入 Panama 項目中了,該特性正在積極地開發中。
判決:正在進行中(做爲 Panama 項目的一部分)
即便在局部(或文件做用域)級別,也沒有認真嘗試擴展導入語法的做用域或引入類型別名。
判決:尚不予考慮
在 Java 9 中添加了接口上的靜態方法,而且對集合進行了更新,以包括用於集合的工廠方法。它們在 Java 中扮演集合字面量(Collection Literals)的角色:
1var ls = List.of(1,2,3);
因爲工廠扮演字面量的角色時,此變動還引入了集合接口的新實現。這些實現是不可變的,由於重用現有的可變集合(例如 ArrayList)將違反程序員的指望,即這些值應該表現得像字面量同樣。
更具侵入性的解決方案,例如將新字面量直接引入到語言語法中,則不予採用。
判決:已交付(做爲工廠方法)
Java 中的代數數據類型(Algebraic Data Type)正在交付中。該特性包括對類型系統的兩個主要補充:記錄(Records)和密封類型(Sealed Types)以及模式匹配,這是一種很是重要的新語法。
Java 14 提供了這兩個方面的預覽版,具體來講是:記錄(Records),在 Java 中本質上是命名元組;以及模式匹配的初始組件。
組成模式匹配介紹部分的新特性是 Java 的首個模式形式: instanceof 模式和 switch 表達式的標準化版本。
第二個是腳手架(Scaffolding),它將最終支持通用模式匹配的引入,可能會以相似 Scala 程序員所熟悉的匹配表達式的方式引入。
在該特性徹底交付以前,還有許多步驟須要執行:記錄和模式仍然只是處於預覽狀態。所以,須要進一步的 JEP(包括 JEP 375 ,它擴展了 instanceof 模式來析構記錄)來充實整個模式匹配。
隨着 Java 14 的到來,關鍵的 JEP(包括 JEP 375 和 JEP 360 ,它們引入了密封類型)並非任何特定 Java 版本的目標。
儘管缺少具體的路線圖,但整個代數數據類型和模式匹配機制頗有可能能夠在下一個 LTS 版本(即 2021 年 9 月的 Java 17)中以標準化的形式及時交付。
判決:正在進行中(做爲 Amber 項目的一部分)
自 Java 8 以來,Java 的類型系統已經有了必定程度的發展,可是在實踐中並無朝着通用的結構類型的方向發展。例如,在設計記錄時,爲了使記錄成爲命名類型,顯式地拒絕告終構類型。
這就強化了這樣一個觀念,即咱們賦予類型的名稱具備強大的力量和重要性,Java 記錄不只僅是由其組件的數量和類型來定義的。
在 Java 中,相似於結構類型的東西仍然隱約可見的一個小地方是在 Java 的不可表示類型中。實際上,這些只是最初在 2015 年文章中討論的示例的一個擴展。
在這個例子中,咱們構造了一個看起來像結構類型的對象(Object + ),但只能在單個表達式中使用它,由於沒有可表示的類型可以用做可賦值的變量類型。
從 Java 10 開始,該語言就已經具備類型推斷的擴展形式了,類型推斷使用 var 來減小賦值中的樣板。咱們可以使用此特性來 http://extend the scope">擴展做用域,在做用域內,咱們能夠調用以這種方式定義在類型上的其餘方法。可是,這僅限於發生類型推斷的方法。 var 推斷的特殊類型不能精確地跨越方法的邊界,由於它是不可表示的。
實際上,這些特殊案例並非真正的結構類型,也沒有引入它的意圖。 Java 的設計對名稱和命名類型的吸引力太強了。
判決:考慮過但駁回了
在過去的五年中,對 invokedynamic 的使用已經有了很大的擴展,儘管只是在 JDK 和少許技術成熟的外部庫中。
正如原文所述,「Java 語言沒有關鍵字或其餘結構來建立通用的 invokedynamic 調用點」。
關於能夠擴展 Dynalink 庫來承擔這個角色的建議從未被採納過,實際上,產生 Dynalink 的 Nashorn Javascript 實現自己如今也已經被棄用了,能夠從 Java 15 中刪除(儘管 Dynalink 自己將保留)。
那些真正使用動態調用點的庫經過 MethodHandles API 來實現的,儘管該方法在 2020 年使用起來會稍微容易一些,可是對大多數 Java 程序員來講,它仍然是高不可攀的。
在不引起太多運行時問題的靈活動態調用和引人注目的語言級別使用之間,尋求平衡的困難已經被證實了,該困難至少在目前是很是巨大的。
判決:尚不予考慮
在過去的 5 年裏,也出現了一些項目和趨勢,這些項目和趨勢我並無在最初的文章中預測或解決。其中最重要的多是:
舉幾個例子:
儘管 Valhalla 項目是於 2014 年啓動的,但在隨後的幾年裏,它勢頭強勁並取得了巨大的發展。它已經成爲 Java 迄今爲止最雄心勃勃、最大的變化了。 Valhalla 承諾將會修改 Java 平臺的各個方面:從內存和值在 VM 中的表示方式,到類型系統和泛型,再到庫級和語言級語法。
該項目旨在使 Java 與當前和將來的硬件狀態保持一致,並提供性能和其餘一些根本沒法單獨解決的改進。相反,Valhalla 的目標是將 Java 平臺的狀態從當前位置(咱們能夠認爲是局部最大值)轉移到一個更適合做爲將來幾十年平臺基礎的位置。
最初的研究老是很難預測的,所以 Graal 的興起也讓我感到驚訝,但也不足爲奇。與其餘許多引人入勝的概念同樣,一旦你掌握了它,它的基本概念就會變得很是簡單。
Java 經常使用的 JIT 編譯器是用 C++ 代碼編寫的,並在 JVM 特殊的專用線程上執行。 Graal 從一個簡單的想法開始:若是 JIT 編譯器是用 Java 編寫的,而實際上編譯器線程正在運行的是 Java 解釋器的第二個副本,那該怎麼辦?
解釋模式的 JIT 編譯器將具備與當前 JIT 相同的特性。所以它能夠將任何類文件編譯爲機器碼。咱們應該預期它會比現有的 C++ 編譯器慢,但它的行爲並不會有所不一樣,只是在性能上不一樣。
將此想法歸結爲邏輯結論,這意味着解釋模式 JIT 能夠編譯構成 JIT 自己的類文件。一旦預熱,它就能夠替換本身,並以與原始的原生 JIT 相同的性能運行。
事實證實,這個引人入勝的想法是一大類新技術的起點,其中包括 Java 的本地編譯(AOT)以及可以運行多種不一樣語言的全新的多語言虛擬機(GraalVM)。
在過去的五年中,Java 平臺已經變得愈來愈複雜了,有許多新的語言和虛擬機(VM)特性已經交付或正在開發。假設按照當前的趨勢繼續下去,社區最感興趣的多是在 Java 17(將於 2021 年 9 月發佈)中提供的一組標準化的特性。
這將是一個大相徑庭的 Java, 與咱們在 2014 年最初觀察時的 Java 不一樣,雖然某些特性已經交付了,但彷佛很明顯,其餘一些特性不太可能實現了,還有一些特性是經過徹底不一樣的形式實現的。咱們期待着看到將來五年 Java 語言和平臺的發展,尤爲是那些咱們目前尚沒法預測的方面。