Java 10 新特性解密,引入類型推斷機制

2020-12-25 開源中國

隨著Java開發工具包(JDK)9的發布,大量的注意力都集中在Java的最新特性上,包括引入模塊(通過集成項目Jigsaw)。儘管最近的很多關注都集中在這些強大的新功能上,但下一個版本的Java:JDK 10已經開始準備了。在本文中,我們將粗略地介紹一下JDK 10的主要特性,並探討JDK 10中可能包含的一些特性。

請注意,本文中所包含的信息在寫本文時是準確的。但是到發布時,JDK 10特性組預計將會增加。

新功能

與之前的JDK版本一樣,對於即將到來的JDK 10也有一些主要特性。這些特性可以分為兩個主要類別:(1)目標發布,(2)建議發布。前者表示某些特性已計劃在JDK 10中發布,後一種類型表示這些特性還需要增加支持和成熟度。一旦條件允許,它就可以升級為一個目標發布狀態。

目標發布

目前有兩個主要功能針對JDK 10:

  • 局部變量類型推斷,這將刪除大部分對象實例化所需的冗長的包含手動類型信息

  • 整合源樹source tree的JDK庫,即不同的JDK庫將被合併成一個單一的存儲庫。

1. 局部變量類型推斷

強類型程式語言有很多優點,包括在編譯時發現類型錯誤,但是它們也引入了大量的樣板代碼,特別是在定義局部變量時。例如,當我們希望實例化一個對象時,我們被迫在賦值的左側提供顯式類型,並在賦值的右邊提供實現類型,如下面的片段所示:

MyObject value = new MyObject();

但是,當這個過程重複出現大量任務時,對象實例化可能變得令人沮喪和乏味。許多最流行的強類型的程式語言,比如C++, C#以及Go,在定義過程中,提供一種局部變量類型推斷的功能(例如C++提供了auto 關鍵字,C#提供var關鍵字)。但是,Java仍缺乏這樣的功能,它要求開發人員顯式聲明變量的預期清單類型。

為了解決這個問題,Java開發工具包(JDK)改進建議(JEP)286提出了一個上下文敏感的關鍵字var,允許局部變量被以下方式初始化:

var value = new MyObject();var list = new ArrayList<MyObject>();

由於var關鍵字是上下文敏感的,它的使用有下面的規則定義:

代碼使用var作為一個變量、方法或包名稱時將不受影響;而使用var作為類或接口名稱的代碼將受到影響。

同樣,類型推斷將受到以下方式的約束:

推斷類型將被限制在局部變量的初始化,增強的for循環索引,以及傳統的for循環中聲明;它(將)不用於方法形式、構造函數形式、方法返回類型、欄位、捕獲形式,或任何其他類型的變量聲明。

考慮到所有的限制和細微差別,這個特性將有助於在開發人員創建的應用程式Java代碼中減輕大量的單調無聊的動作,並簡化JDK代碼庫。更多信息可以在官方的JEP 286規範中找到。

2. 整合的JDK庫

目前,有8個不同的Mercurial存儲庫用於存儲包含JDK的大量原始碼:

  • root

  • corba

  • hotspot

  • jaxp

  • jaxws

  • JDK

  • langtools

  • nashorn

雖然過多的存儲庫提供了對組成JDK的各種組件並清晰分離,但管理多個存儲庫存在一些主要的缺點。

其中最重要的一點是,在JDK的兩個不同部分,單個錯誤修復程序不能被原子跟蹤。例如,如果一個bug修復需要對獨立存儲庫中包含的系統的兩個部分進行更改,那麼必須提交兩個提交:每個存儲庫中一個。這種不連續性很容易地降低項目和原始碼管理工具的可跟蹤性和複雜性。

為了解決這個問題,JEP 296建議將所有現有存儲庫合併到一個Mercurial存儲庫中。這種合併的一個次生效應是,這個單一的Mercurial存儲庫比現有的8個存儲庫要更容易的被鏡像(作為一個Git存儲庫)。

雖然在這個整合過程中,外部開發人員有一些阻力,但是JDK開發團隊似乎已經致力於使這一更改成為JDK 10的一部分。有關更多信息,請參見JEP 296,並提議整合由Michael Redlich發布的JDK 10 OpenJDK Mercurial存儲庫聲明。

建議發布

除了兩個目標特性之外,JDK 10目前還有三個建議,其中兩個主要是對JDK的垃圾收集器部分進行升級,另一個側重於對JDK的本地線程功能進行升級。

1 .清理垃圾收集接口

在當前的JDK結構中,組成垃圾收集器(GC)實現的組件分散在代碼庫的各個部分。儘管這些慣例對於使用GC計劃的JDK開發者比較熟悉,但對新的開發人員來說,對於特定GC的原始碼,或者創建一個新的GC常常會感到困惑。更重要的是,隨著Java modules的出現,我們希望在構建過程中排除不需要的GC,但是GC接口的當前橫切結構排除了這種增強。

JEP 304被設計為解決此問題的方案,並建議整合併清理GC接口,以便更容易地實現新的GC,並更好地維護現有的GC。本建議完成後,GC執行將負責提供以下內容:

  •  heap,CollectedHeap的子類

  •  barrier set,BarrierSet的子類,它實現了運行時的各種障礙

  •  一個CollectorPolicy的實現

  •  GCInterpreterSupport的實現,它實現了解釋器的GC的各種障礙(使用彙編指令)

  •  GCC1Support的實現,它為C1編譯器實現了GC的各種障礙

  •  GCC2Support的實現,它為C2編譯器實現了GC的各種障礙

  •  最終GC特定參數的初始化

  •  設置MemoryService、相關的內存池、內存管理器等。

有關這些更改的更多信息,請參見JEP 304規範;有關Java GC的更多信息,請參閱Oracle提供的垃圾收集器基礎指南。

2. G1垃圾收集器並行化

隨著JDK 9的發布,Garbage-First(G1)GC取代了Parallel Collector作為默認GC。為了減少JDK 9之外的JDK版本中垃圾收集的影響,G1收集器將被並行化(以匹配並行收集器的特徵)。雖然目前還沒有關於這個並行化的實現細節的信息,但是可以在JEP 307規範中找到關於此更改的更多細節。

有關GC實現的更多信息,請參閱Oracle的G1指南和並行收集器指南。

3. 項目線程局部握手

當前,停止Java線程是一個「全部或沒有」的過程,需要一個Java虛擬機(JVM)的安全點,以使一個線程停止。為了讓單獨的線程停止,JEP 312提議將回調包含到線程中。這一更改受到了限制,因為它顯著地提高了現有JVM功能的性能開銷,並且改變了到達JVM全局安全點的現有時間語義。有關這個建議的更多信息,請參閱JEP 312的Thread-Local Handshake OpenJDK討論。

結論

儘管JDK 9對於許多Java開發人員非常新鮮,但它的發展並沒有停止。特別是,JDK 10承諾為局部變量實例化引入類型推斷機制,並將現有的JDK存儲庫合併到一個Mercurial存儲庫中。

此外,在更成熟和更支持的情況下,JDK 10還可能包括一些重要的升級到GC接口和默認的GC實現,以及升級到JVM中單個線程的可尋址能力。雖然JDK 10的發布在未來仍然相對較遠,而且包含的特性很可能會成為Java時間軸上的一個重要裡程碑。

來源:CodeBay

相關焦點

  • 最通俗易懂的 Java 10 新特性講解|原力計劃
    10 就是這麼一個小版本,因為 Java 的後續版本基本都會包含之前新特性,所以還是把 Java 10 帶來的改變單獨寫一寫。JEP 322 - 基於時間的版本號就像上面說的,Java 調整了發布策略,為了適應這種發布節奏,隨之改變的還有 Java 版本號的記錄方式。版本號的新模式是:$FEATURE.$INTERIM.$UPDATE.
  • Java新特性:數據類型可以扔掉了?
    然而到了 JDK 10 時,我們就有了新的選擇,JDK 10 中新增了 var 局部變量推斷的功能,使用它我們可以很 happy 的忘記數據類型這件事了,那它是如何使用的呢?接下來我們一起來看。使用對比接下來我們就使用對比的方式,來體會一下 var 的作用。
  • 關於每個版本特性的Java 面試題
    2、如果將javac設置為了Java5以下,那麼靜態導入等jdk1.5的特性都會報告錯誤。7)新的線程模型和並發庫Thread Framework(重要)答: 最主要的就是引入了 java.util.concurrent 包,這個都是需要重點掌握的。
  • Java 15 即將到來,新特性速覽!
    在發布前夕,我們不妨先一窺新版 JDK 的新特性:第二個外部內存訪問 API(孵化階段),它將使 Java 程序安全高效地訪問 Java 堆以外的外部存儲器。該 API 應該能夠在各種外部內存(如本機、持久和託管堆)上進行操作。
  • JAVA8 新特性詳解
    -> {//方法體}說明:(參數1,參數2…)表示參數列表;->表示連接符;{}內部是方法體1、=右邊的類型會根據左邊的函數式接口類型自動推斷;>2、如果形參列表為空,只需保留();3、如果形參只有1個,()可以省略,只需要參數的名稱即可;4、如果執行語句只有1句,且無返回值,{}可以省略,若有返回值,則若想省去{},則必須同時省略return,且執行語句也保證只有1句;5、形參列表的數據類型會自動推斷;
  • 【終極版】Java8 新特性全面介紹,強烈建議收藏
    與lambda聯合使用,方法引用可以使語言的構造更緊湊簡潔,減少冗餘代碼默認方法:默認方法就是一個在接口裡面有了一個實現的方法Stream API:新添加的Stream API(java.util.stream) 把真正的函數式編程風格引入到Java中。
  • Java 8新特性:學習如何使用Lambda表達式(一)
    我將分為兩篇系列文章來描述了使用Java 8的新特性 - lambda表達式。
  • Java 中 Varargs 機制的理解
    藉助這一特性,就可以順利的完成轉發了。清單9:轉發收到的實參們清單10:一個「cannot be applied to」的編譯錯誤如果不能修改原來的類,為要調用的方法增加參數個數可變的版本,而又想採用這種簡明的調用方式,那麼可以藉助「引入外加函數(Introduce Foreign Method)」和「引入本地擴展(Intoduce Local Extension)」的重構手法來近似的達到目的。7. 當個數可變的實參遇到泛型J2SE 1.5中新增了「泛型」的機制,可以在一定條件下把一個類型參數化。
  • Java基礎知識點面試手冊(線程+JDK8)
    此為下篇,內容包括:高並發編程,Java8新特性。高並發編程多線程和單線程的區別和聯繫:答:在單核 CPU 中,將 CPU 分為很小的時間片,在每一時刻只能有一個線程在執行,是一種微觀上輪流佔用 CPU 的機制。
  • Java反射機制深入詳解
    反射是java語言的一個特性,它允程序在運行時(注意不是編譯的時候)來進行自我檢查並且對內部的成員進行操作。例如它允許一個java的類獲取他所有的成員變量和方法並且顯示出來。Java 的這一能力在實際應用中也許用得不是很多,但是在其它的程序設計語言中根本就不存在這一特性。例如,Pascal、C 或者 C++ 中就沒有辦法在程序中獲得函數定義相關的信息。
  • Java的「泛型」特性,你以為自己會了?(萬字長文)
    # 泛型(generics) 他是 JDK5 中引入的一個新特性,泛型提供了編譯時類型安全監測機制,該機制允許我們在編譯時檢測到非法的類型數據結構。- (表示不確定的java類型)但是泛型的參數只能是類類型,不能是基本的數據類型,他的類型一定是自Object的注意:泛型不接受基本數據類型,換句話說,只有引用類型才能作為泛型方法的實際參數2. 為什麼要使用泛型?
  • pacebox-springboot 1.1.5 發布,java 生態框架
    案例 inter-boot-demo  boot版demo inter-micro-demo  cloud版demo(nacos+sentinel體系+權限管理+elasticsearch日誌+數據加解密+分布式追蹤(基於opentracing)) inter-boot-generator
  • Java 類型信息詳解和反射機制
    點擊上方藍色字體,選擇「標星公眾號」優質文章,第一時間送達  作者 |  低吟不作語來源 |  urlify.cn/BnyARn66套java從入門到精通實戰課程分享1、RTTIRTTI(RunTime Type Information)運行時類型信息,能夠在程序運行時發現和使用類型信息,把我們從只能在編譯期知曉類型信息並操作的局限中解脫出來傳統的多態機制正是 RTTI 的基本使用:假設有一個基類 Shape 和它的三個子類 Circle、Square、Triangle,現在要把
  • Java中volatile特性概述
    volatile特性概述volatile總體概覽在上節中,我們已經研究完了volatile可以實現並發下共享變量的可見性,除了volatile可以保證可見性外,volatile 還具備如下一些突出的特性:volatile的原子性問題:volatile
  • 編程沒有銀彈:探討 Java 8 新增特性的優缺點
    LambdaJava 8的另一大亮點是引入Lambda表達式,使用它設計的代碼會更加簡潔。當開發者在編寫Lambda表達式時,也會隨之被編譯成一個函數式接口。下面這個例子就是使用Lambda語法來代替匿名的內部類,代碼不僅簡潔,而且還可讀。
  • 給Java新手的一些建議——Java知識點歸納(Java基礎部分)
    在JVM這個大類中,我認為需要掌握的知識有:JVM內存模型和結構GC原理,性能調優調優:Thread Dump, 分析內存結構class 二進位字節碼結構, class loader 體系 , class加載過程 , 實例創建過程方法執行過程Java各個大版本更新提供的新特性(需要簡單了解)
  • Java 11新特性:棄用Nashorn JavaScript引擎
    Java 11將聲明棄用Nashorn JavaScript腳本引擎,相關API和jjs工具,並在未來的版本中移除這些特性。Nashorn JavaScript引擎在Java 8中首次引入,完整實現了ECMAScript-262 5.1標準。
  • Java泛型總結
    什麼是泛型泛型是jdk5引入的類型機制,就是將類型參數化,它是早在1999年就制定的jsr14的實現。泛型機制將類型轉換時的類型檢查從運行時提前到了編譯時,使用泛型編寫的代碼比雜亂的使用object並在需要時再強制類型轉換的機制具有更好的可讀性和安全性。
  • Java基礎教程:java反射機制教程
    這時候java語言在設計的時候為我們提供了一個機制,就是反射機制,他能夠很方便的去解決我們的問題。 二、深入分析java反射機制 1、獲取Class類 在java中萬事萬物皆對象,Useruser=newUser()一行代碼我們知道了user是User類的實例對象,通過Studentstu=newStudent()我們知道了
  • Java 中的 6 顆語法糖
    在早期的JDK中,只能通過Object類是所有類型的父類和強制類型轉換來實現泛型的功能。強制類型轉換的缺點就是把編譯期間的問題延遲到運行時,JVM並不能為我們提供編譯期間的檢查。在JDK1.5中,Java語言引入了泛型機制。但是這種泛型機制是通過類型擦除來實現的,即Java中的泛型只在程序原始碼中有效(原始碼階段提供類型檢查),在編譯後的字節碼中自動用強制類型轉換進行替代。