JDK10 新特性

想更詳細的瞭解JDK10新特性能夠瀏覽官方介紹html

JDK10 新特性目錄導航:java

  • 局部變量類型推斷
  • 將JDK多存儲庫合併爲單儲存庫
  • 垃圾回收接口
  • 並行Full GC 的G1
  • 應用數據共享
  • 線程局部管控
  • 移除Native-Header Generation Tool (javah)
  • Unicode 標籤擴展
  • 備用內存設備上分配堆內存
  • 基於實驗JAVA 的JIT 編譯器
  • Root 證書
  • 基於時間的版本控制

局部變量類型推斷

不少人抱怨Java是一種強類型,須要引入大量的樣板代碼。甚至在這些狀況下,給定好變量名,一般很清楚發生了什麼,明顯類型聲明每每被認爲是沒必要要的。許多流行的編程語言都已經支持某種形式的局部變量類型推斷:如C++ (auto), C# (var), Scala (var/val), Go (declaration with :=)等。算法

JDK10 可使用var做爲局部變量類型推斷標識符,此符號僅適用於局部變量,加強for循環的索引,以及傳統for循環的本地變量;它不能使用於方法形式參數,構造函數形式參數,方法返回類型,字段,catch形式參數或任何其餘類型的變量聲明。數據庫

標識符var不是關鍵字;相反,它是一個保留的類型名稱。這意味着var用做變量,方法名或則包名稱的代碼不會受到影響;但var不能做爲類或則接口的名字(但這樣命名是比較罕見的,由於他違反了一般的命名約定,類和接口首字母應該大寫)。編程

參考一下示例:安全

var str = "ABC"; //根據推斷爲 字符串類型
var l = 10L;//根據10L 推斷long 類型
var flag = true;//根據 true推斷 boolean 類型
var flag1 = 1;//這裏會推斷boolean類型。0表示false 非0表示true
var list = new ArrayList<String>();  // 推斷 ArrayList<String>
var stream = list.stream();          // 推斷 Stream<String>

反編譯class文件:架構

String str = "ABC";
long l = 10L;
boolean flag = true;
int flag1 = true;
ArrayList<String> list = new ArrayList();
Stream<String> stream = list.stream();

從上面示例能夠看出,當咱們是用複雜的方法時,不須要特地去指定他的具體類型返回,可使用var推斷出正確的數據類型,這在編碼中,能夠大幅減小咱們對方法返回值的探究。oracle

將JDK多存儲庫合併爲單存儲庫

爲了簡化和簡化開發,將JDK多存儲庫合併到一個存儲庫中。多年來,JDK的完整代碼已經被分解成多個存儲庫。在JDK9 中有八個倉庫:root、corba、hotspot、jaxp、jaxws、jdk、langtools和nashorn。在JDK10中被合併爲一個存儲庫。框架

雖然這種多存儲庫模型具備一些有點,但它也有許多缺點,而且在支持各類可取的源代碼管理操做方面作得不好。特別是,不可能在相互依賴的變動存儲庫之間執行原子提交。例如,若是一個bug修復或RFE的代碼如今同時跨越了jdk和hotspot 存儲庫,那麼對於兩個存儲庫來講,在託管這兩個不一樣的存儲庫中,對兩個存儲庫的更改是不可能實現的。跨多個存儲庫的變動是常見。編程語言

垃圾回收接口

這不是讓開發者用來控制垃圾回收的接口;而是一個在 JVM 源代碼中的容許另外的垃圾回收器快速方便的集成的接口。

垃圾回收接口爲HotSpot的GC代碼提供更好的模塊化;在不影響當前代碼的基礎狀況下,將GC添加到HotSpot變的更簡單;更容易從JDK構建中排除GC。實際添加或刪除GC不是目標,這項工做將使HotSpot中GC算法的構建時間隔離取得進展,但它不是徹底構建時間隔離的目標。

並行Full GC 的G1

JDK10 經過並行Full GC,改善G1的延遲。G1垃圾收集器在JDK 9中是默認的。之前的默認值並行收集器中有一個並行的Full GC。爲了儘可能減小對使用GC用戶的影響,G1的Full GC也應該並行。

G1垃圾收集器的設計目的是避免Full收集,可是當集合不能足夠快地回收內存時,就會出現徹底GC。目前對G1的Full GC的實現使用了單線程標記-清除-壓縮算法。JDK10 使用並行化標記-清除-壓縮算法,並使用Young和Mixed收集器相同的線程數量。線程的數量能夠由-XX:ParallelGCThreads選項來控制,可是這也會影響用Young和Mixed收集器的線程數量。

應用數據共享

爲了提升啓動和內存佔用,擴展示有的類數據共享(CDS)特性,容許將應用程序類放置在共享檔案中。

  • 經過在不一樣的Java進程間共享公共類元數據來減小佔用空間。
  • 提高啓動時間。
  • CDS容許未來自JDK的運行時映像文件($JAVA_HOME/lib/modules)的歸檔類和應用程序類路徑加載到內置平臺和系統類加載器中。
  • CDS容許將歸檔類加載到自定義類加載器中。

線程局部管控

在不執行全局VM安全點的狀況下對線程執行回調的方法。讓它中止單個線程而不是所有線程。

移除Native-Header Generation Tool (javah)

JDK10 從JDK中移除了javah 工具。該工具已被JDK8 (JDK-7150368)中添加javac高級功能所取代。此功能提供了在編譯java源代碼時編寫本機頭文件的功能,從而無需使用單獨的工具。

Unicode 標籤擴展

JDK10 改善 java.util.Locale 類和相關的 API 以實現額外 BCP 47 語言標籤的 Unicode 擴展。尤爲如下擴展支持:

  • cu:貨幣類型
  • fw:一週的第一天
  • rg:區域覆蓋
  • tz:時區

爲支持以上擴展,JDK10對如下API進行更改:

  • java.text.DateFormat::get*Instance:將根據擴展ca、rg或tz返回實例。
  • java.text.DateFormatSymbols::getInstance:將根據擴展rg返回實例。
  • java.text.DecimalFormatSymbols::getInstance:將根據擴展rg返回實例。
  • java.text.NumberFormat::get*Instance:將根據nu或rg返回實例。
  • java.time.format.DateTimeFormatter::localizedBy:將返回DateTimeFormatter 根據ca,rg或rz的實例。
  • java.time.format.DateTimeFormatterBuilder::getLocalizedDateTimePattern:將根據rg返回String。
  • java.time.format.DecimalStyle::of:將返回DecimalStyle根據nu或rg的實例。
  • java.time.temporal.WeekFields::of:將返回WeekFields根據fw或rg的實例。
  • java.util.Calendar::{getFirstDayOfWeek,getMinimalDaysInWeek}:將根據fw或rg返回值。
  • java.util.Currency::getInstance:將返回Currency根據cu或rg返回實例。
  • java.util.Locale::getDisplayName:將返回一個包含這些U擴展名的顯示名稱的字符串。
  • java.util.spi.LocaleNameProvider:將爲這些U擴展的鍵和類型提供新的SPI。

備用內存設備上分配堆內存

啓用HotSpot VM以在用戶指定的備用內存設備上分配Java對象堆。隨着廉價的NV-DIMM內存的可用性,將來的系統可能配備了異構的內存架構。這種技術的一個例子是英特爾的3D XPoint。這樣的體系結構,除了DRAM以外,還會有一種或多種類型的非DRAM內存,具備不一樣的特徵。具備與DRAM具備相同語義的可選內存設備,包括原子操做的語義,所以能夠在不改變現有應用程序代碼的狀況下使用DRAM代替DRAM。全部其餘的內存結構,如代碼堆、metaspace、線程堆棧等等,都將繼續駐留在DRAM中。

參考如下使用案例:

  • 在多JVM部署中,某些JVM(如守護進程,服務等)的優先級低於其餘JVM。與DRAM相比,NV-DIMM可能具備更高的訪問延遲。低優先級進程能夠爲堆使用NV-DIMM內存,容許高優先級進程使用更多DRAM。
  • 諸如大數據和內存數據庫等應用程序對內存的需求不斷增長。這種應用能夠將NV-DIMM用於堆,由於與DRAM相比,NV-DIMM可能具備更大的容量,成本更低。

基於實驗JAVA 的JIT 編譯器

啓用基於Java的JIT編譯器Graal,將其用做Linux / x64平臺上的實驗性JIT編譯器。Graal是一個基於Java的JIT編譯器,它是JDK 9中引入的Ahead-of-Time(AOT)編譯器的基礎。使它成爲實驗性JIT編譯器是Project Metropolis的一項舉措,它是下一步是研究JDK的基於Java的JIT的可行性。

使Graal可用做實驗JIT編譯器,從Linux / x64平臺開始。Graal將使用JDK 9中引入的JVM編譯器接口(JVMCI)。Graal已經在JDK中,所以將它做爲實驗JIT將主要用於測試和調試工做。要啓用Graal做爲JIT編譯器,請在java命令行上使用如下選項:

-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler

Root 證書

在JDK中提供一組默認的root 認證權威(CA)證書。在Oracle的Java SE根CA程序中開源root證書,以使OpenJDK構建對開發人員更有吸引力,並減小這些構建和Oracle JDK構建之間的差別。

cacerts密鑰存儲庫是JDK的一部分,它的目的是包含一組root證書,這些root證書能夠用來在各類安全協議中使用的證書鏈中創建信任。然而,JDK源代碼中的cacerts密鑰庫目前是空的。所以,諸如TLS之類的關鍵安全組件在OpenJDK構建中不會默認工做。爲了解決這個問題,用戶必須配置和填充cacerts密鑰庫,並使用一組root證書來記錄,例如, JDK 9 release notes

基於時間的版本控制

JEP 223 引入的版本字符串方案比以往有了顯著的改進,可是,該方案並不適合將來,如今Java SE平臺和JDK的新版本嚴格按照六個月的節奏發佈。JEP 223方案的主要困難在於發行版的版本號對於其前身的重要性和兼容性進行了編碼。然而,在基於時間發佈模式中,這些品質並非事先知道的。在發佈的開發週期中,它們可能會發生變化,直到最終的功能被集成爲止。所以發佈的版本號也是未知的。

使用JEP 223的版本號語義,每一個在JDK發佈版上工做或者在其上構建或使用組件的人都必須先說明發布的發佈日期,而後切換到說版本號,已知。維護庫,框架和工具的開發人員必須準備好更改在每一個JDK發佈週期後期檢查版本號的代碼。這對全部參與者來講都很尷尬和混亂。

所以,這裏提出的主要改變是從新編制版本號來編碼,而不是編碼的兼容性和重要性,而是按照發布週期的時間推移。這是更適合基於時間的發佈模型,由於每一個發佈週期,所以每一個發佈的版本號,老是提早知道。

後續的版本格式爲:[1-9][0-9]*((\.0)*\.[1-9][0-9]*)*

該格式能夠是任意長度,但前四個被賦予特定含義,如:$FEATURE.$INTERIM.$UPDATE.$PATCH

  • $FEATURE:功能發佈計數器,無論發佈內容如何,都會爲每一個功能發佈增長。功能可能會添加到功能發佈中; 若是提早通知提早至少發佈一次功能發佈,它們也可能會被刪除。若是合理,可能會作出不兼容的更改。
  • $INTERIM:臨時版本計數器,對於包含兼容錯誤修復和加強功能的非功能版本遞增,但沒有不兼容的更改,沒有功能移除,也沒有對標準API的更改。
  • $UPDATE:更新版本計數器增長了兼容更新版本,可解決新功能中的安全問題,迴歸和錯誤。
  • $PATCH:緊急修補程序釋放計數器只有在須要生成緊急釋放以解決關鍵問題時纔會增長。

版本號永遠不會有零元素結尾。若是一個元素及其後的全部元素在邏輯上具備零值,那麼它們所有被省略。

在嚴格六個月的發佈模式下,版本號以下所示:

  • $FEATURE 每六個月增長一次。如:2018年3月發佈的是JDK 10,2018年9月發佈的是JDK 11,等等。
  • $INTERIM 老是爲零,由於六個月的模型不包括臨時版本。在此爲保留其靈活性,以便未來對版本模型的修訂可能包括此類版本。
  • $UPDATE 在$FEATURE發佈後的一個月遞增,以後每三個月遞增一次:如2018年4月發佈JDK 10.0.1。7月發佈的是JDK 10.0.2等等。\
相關文章
相關標籤/搜索