JDK 10 的 109 項新特性

來源:開源中國,java

www.oschina.net/translate/109-new-features-in-jdk-10bootstrap

雖然感受 JDK9 發佈才僅僅幾周的時間,然而,隨着新的 OpenJDK 的發佈節奏,JDK10 已經到達發佈候選里程碑階段。數組

我看過各類關於 JDK10 新特性的博客,可是它們都傾向於關注經過 JEPS 定義的大方面。這篇博文,我將看看是否能夠羅列出 JDK10 中已經發生變化的方方面面(包括新增的和剔除的)。安全

有時候,我會作一些關於 Java SE 的報告會。以前我在「 JDK9 的 55 個新特性」的報告會上曾開玩笑說:下次我將作的恐怕是「 JDK10 的 5 個新特性」。然而事實證實,即便僅有六個多月的開發時間,JDK10 依然超乎想象。微信

即使我再也不爲 Oracle 工做,我也在此先作一個「安全港聲明」,以便消除誤會。這個列表是由下面這些公開可用的信息整理編輯的:JDK Enhancement Proposals (JEPs)、the OpenJDK bug database 和 Java SE 10 public review specification (JSR 383) 。固然,儘管我已儘量的研究以保證信息準確,但在 JDK 10 最終發佈以前仍可能會發生變化。dom

大事記ide

JDK10 包含 12 個JEP (改善提議):函數

  • 【286】局部變量類型推斷 :對於開發者來講,這是 JDK10 惟一的真正特性。它向 Java 中引入在其餘語言中很常見的 var ,好比 JavaScript 。只要編譯器能夠推斷此種類型,你再也不須要專門聲明一個局部變量的類型。一個簡單的例子是:工具

var x = new ArrayList<String>();性能

這就消除了咱們以前必須執行的 ArrayList<String> 類型定義的重複。我鼓勵大家去讀 JEP ,由於上面有一些關於這個句法是否能用的規則。

有趣的是,須要注意 var 不能成爲一個關鍵字,而是一個保留字。這意味着你仍然可使用 var 做爲一個變量,方法或包名,可是如今(儘管我肯定你毫不會)你不能再有一個類被調用。

  • [310]應用類數據共享(CDS) :CDS 在 JDK5 時被引進以改善 JVM 啓動的表現,同時減小當多個虛擬機在同一個物理或虛擬的機器上運行時的資源佔用。JDK10 將擴展 CDS 到容許內部系統的類加載器、內部平臺的類加載器和自定義類加載器來加載得到的類。以前,CDS 的使用僅僅限制在了 bootstrap 的類加載器。

  • [314]額外的 Unicode 語言標籤擴展:這將改善 java.util.Locale 類和相關的 API 以實現額外 BCP 47 語言標籤的 Unicode 擴展。尤爲是,貨幣類型,一週的第一天,區域覆蓋和時區等標籤如今將被支持。

  • [322]基於時間的版本控制:正如我在以前的博客中所討論的,咱們的 JDK 版本字符串格式幾乎與 JDK 版本同樣多。有幸的是,這是最後須要使用到的,咱們能夠堅持用它。這種格式使用起來很像 JDK9 中介紹的提供一個更加語義的形式。有一件困擾個人事是包含了一個 INTERIM 元素,正如 JEP 提議中所說,「永遠是0」。好吧,若是永遠是0,那它有什麼意義呢?他們說這是爲將來使用作保留,但我仍不是很贊同。我認爲,這有些冗餘繁雜。這也消除了在 JDK9 中有過的至關奇怪的情形。第一次更新是 JDK 9.0.1 , 很是符合邏輯。第二次更新是 JDK 9.0.4 ,不合邏輯。緣由是,在 JDK9 的版本計數模式下,須要留下空白以便應急或不在預期安排的更新使用。但既然沒有更新是必須的,爲何不簡單稱之爲 JDK 9.0.2 呢?

  • [319]根證書:在 JDK 中將提供一套默認的 CA 根證書。關鍵的安所有件,如 TLS ,在 OpenJDK 構建中將默認有效。這是 Oracle 正在努力確保 OpenJDK 二進制和 Oracle JDK 二進制功能上同樣的工做的一部分,是一項有用的補充內容。

  • [307] 並行全垃圾回收器 G1 : G1 是設計來做爲一種低延時的垃圾回收器(可是若是它跟不上舊的堆碎片產生的提高速率的話,將仍然採用完整壓縮集合)。在 JDK9 以前,默認的收集器是並行,吞吐,收集器。爲了減小在使用默認的收集器的應用性能配置文件的差別,G1 如今有一個並行完整收集機制。

  • [313]移除 Native-Header 自動生成工具:Java9 開始了一些對 JDK 的家務管理,這項特性是對它的延續。當編譯 JNI 代碼時,已再也不須要單獨的工具來生成頭文件,由於這能夠經過 javac 完成。在將來的某一時刻,JNI 將會被 Panama 項目的結果取代,可是什麼時候發生還不清楚。

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

  • [312]線程-局部變量管控:這是在 JVM 內部至關低級別的更改,如今將容許在不運行全局虛擬機安全點的狀況下實現線程回調。這將使得中止單個線程變得可能和便宜,而不是隻能啓用或中止全部線程。

  • [316]在備用存儲裝置上的堆分配:硬件技術在持續進化,如今可使用與傳統 DRAM 具備相同接口和相似性能特色的非易失性 RAM 。這項 JEP 將使得 JVM 可以使用適用於不一樣類型的存儲機制的堆。

  • [317] 試驗性的基於 Java 的 JIT 編譯器:最近宣佈的 Metropolis 項目,提議用 Java 重寫大部分 JVM 。乍一想,以爲很奇怪。若是 JVM 是用 Java 編寫的,那麼是否須要一個 JVM 來運行 JVM ? 相應的,這致使了一個很好的鏡像類比。 現實狀況是,使用 Java 編寫 JVM 並不意味着必須將其編譯爲字節碼,你可使用 AOT 編譯,而後在運行時編譯代碼以提升性能。這項 JEP 將 Graal 編譯器研究項目引入到 JDK 中。並給將 Metropolis 項目成爲現實,使 JVM 性能與當前 C++ 所寫版本匹敵(或有幸超越)提供基礎。

  • [296]: 合併 JDK 多個代碼倉庫到一個單獨的儲存庫中:在 JDK9 中,有 8 個倉庫: root、corba、hotspot、jaxp、jaxws、jdk、langtools 和 nashorn 。在 JDK10 中這些將被合併爲一個,使得跨相互依賴的變動集的存儲庫運行 atomic commit (原子提交)成爲可能。

新 API

有 73 項新增內容添加到了標準類庫中。

  • java.awt.Toolkit

    int getMenuShortcutKeyMaskEx(): 肯定哪一個擴展修飾符鍵是菜單快捷鍵的適當加速鍵。

  • java.awt.geom.Path2D:

    void trimToSize(): 將此 Path2D 實例的容量計算到它當前的大小。應用可以使用此操做將路徑的存儲空間最小化。這個方法也被添加到 Path2D.Double 和 Path2D.Float 類。

  • java.io.ByteArrayOutputStream:

    String toString(Charset): 重載 toString(),經過使用指定的字符集解碼字節,將緩衝區的內容轉換爲字符串。

  • java.io.PrintStream:

    lang.io.PrintWriter:

    這兩個類都有三個新的構造函數,它們須要額外的 Charset 參數。

  • java.io.Reader:

    long transferTo(Writer): 從這個 Reader 中讀取全部字符,並按照所讀的順序將字符寫入給定的 Writer 。

  • java.lang.Runtime.Version:

    有四種新方法返回新(JEP 322)版本字符串字段的整數值: feature()、interim()、patch() 和 update() 。

  • java.lang.StackWalker.StackFrame:

    String getDescriptor(): 按照 JVM 標準返回此堆棧幀所表明的方法的描述符。

    String getMethodType():返回此堆棧幀所表明的方法類型,描述參數類型和返回值類型。

  • java.lang.invoke.MethodType:

    Class<?> lastParameterType():返回這個方法類型的最後一個參數類型。若是這個方法類型沒有參數,則返回空類型做爲崗哨值(Sentinel Value)。

  • java.lang.management.RuntimeMXBean:

    long getPid(): R 返回正在運行的 JVM 的進程 ID 。

  • java.lang.management.ThreadMXBean:

    ThreadInfo[] dumpAllThreads(boolean, boolean, int): 返回全部活動線程的線程信息,其中有指定的最大元素數量和同步信息的堆棧跟蹤。

    ThreadInfo[] getThreadInfo(long[], boolean, boolean, int): 返回每一個線程的線程信息,這些線程的標識位於輸入數組中,其中有指定的最大元素數量和同步信息的堆棧跟蹤。

  • java.lang.reflect.MalformedParameterizedTypeException: 添加了一個新的構造函數,它以字符串的形式做爲參數來獲取詳細信息。

  • java.net.URLDecoder:

    java.net.URLEncoder:

    這兩個類都有新的重載的解碼和編碼方法,將 charset 做爲附加參數。

  • java.nio.channels.Channels:

    兩個新的靜態重載方法,容許使用 Charset 的 newReader(ReadByteChannel,Charset)和newWriter(WriteByteChannel,Charset)。

  • java.nio.file.FileStore:

    long getBlockSize(): 在這個文件存儲中返回每一個塊的字節數。

  • java.time.chrono: 這個包裏有三個類,HijrahEra、MiinguoEra 和 ThaiBuddhistEra ,都有一樣的方法。

  • String getDisplayName(TextStyle, Locale): 這將返回用於識別 era 的文本名稱,適合於向用戶展現。

  • java.time.format.DateTimeFormatter:

    localizedBy(Locale): 返回指定格式器的一個副本,其中包含地區、日曆、區域、小數和/或時區的本地化值,這將取代該格式器中的值。

  • java.util: DoubleSummaryStatistics、IntSummaryStatistics 和 LongSummaryStatistics 都有一個新的構造函數,它包含 4 個數值。它使用指定的計數、最小值、最大值和總和構造一個非空實例。

  • java.util.List:

    java.util.Map:

    java.util.Set: 這些接口中的每個都增長了一個新的靜態方法,copyOf(Collection)。這些函數按照其迭代順序返回一個不可修改的列表、映射或包含給定集合的元素的集合。

  • java.util.Optional:

    java.util.OptionalDouble:

    java.util.OptionalInt:

    java.util.OptionalLong: 每個類都有一個新的方法,orElseThrow() ,它本質上和 get() 同樣,也就是說,若是 Optional 有值則返回。不然,將拋出 NoSuchElementException 。

  • java.util.Formatter:

    java.util.Scanner:

    這兩個類都有三個新的構造函數,除了其餘參數以外,它們都帶有一個 charset 參數。

其它翻譯版本(1)

  • java.util.Properties: 這有一個新的構造函數,它接受一個 int 參數。這將建立一個沒有默認值的空屬性列表,而且指定初始大小以容納指定的元素數量,而無需動態調整大小。還有一個新的重載的 replace 方法,接受三個 Object 參數並返回一個布爾值。只有在當前映射到指定值時,纔會替換指定鍵的條目。

  • java.SplittableRandom:

    void nextBytes(byte[]): 用生成的僞隨機字節填充一個用戶提供的字節數組。

  • java.util.concurrent.FutureTask: 添加了 toString() 方法,該方法返回一個標識 FutureTask 的字符串,以及它的完成狀態。在括號中,狀態包含以下字符串中的一個,「Completed Normally」 、「Completed Exceptionally」、 「Cancelled」 或者 「Not completed」。

  • java.util.concurrent.locks.StampedLock:

    boolean isLockStamp(long): 返回一個標記戳表示是否持有一個鎖。

    boolean isOptimisticReadStamp(long): 返回一個標記戳表明是否成功的進行了樂觀讀(optimistic read)。

    boolean isReadLockStamp(long): 返回一個標記戳表示是否持有一個非獨佔鎖(即 read lock )。

    boolean isWriteLockStamp(long): 返回一個標記戳表示是否持有一個獨佔鎖(即 write lock )。

  • java.jar.JarEntry:

    String getRealName(): 返回這個 JarEntry 的真實名稱。若是這個 JarEntry 是一個多版本 jar 文件的入口,它被配置爲這樣處理,這個方法返回的名字是 JarEntry 所表明的版本條目的入口,而不是 ZipEntry.getName() 返回的基本條目的路徑名。若是 JarEntry 不表明一個多版本 jar 文件的版本化條目或者 jar 文件沒有被配置爲做爲一個多版本 jar 文件進行處理,這個方法將返回與 ZipEntry.getName() 返回的相同名稱。

  • java.util.jar.JarFile:

    Stream<JarEntry> versionedStream(): 返回 jar 文件中指定版本的入口對應 Stream 。與 JarEntry 的 getRealName 方法相似,這與多版本 jar 文件有關。

  • java.util.spi.LocaleNameProvider:

    getDisplayUnicodeExtensionKey(String, Locale): 爲給定的 Unicode 擴展鍵返回一個本地化名稱。

    getDisplayUnicodeExtensionType(String, String, Locale): 爲給定的 Unicode 擴展鍵返回一個本地化名稱。

  • java.util.stream.Collectors:

    toUnmodifiableList():

    toUnmodifiableSet():

    toUnmodifiableMap(Function, Function):

    toUnmodifiableMap(Function, Function, BinaryOperator): 這四個新方法都返回 Collectors ,將輸入元素彙集到適當的不可修改的集合中。

  • java.lang.model.SourceVersion: 如今有了一個字段,它表明了 JDK 10 的版本。

    java.lang.model.util.TypeKindVisitor6:

    javax.lang.model.util.TypeKindVisitor9:

    (我必須認可,我歷來沒據說過這些類)

    R visitNoTypeAsModule(NoType, P): 訪問一個 MODULE 的 pseudo-type 。我不肯定爲何只有這兩個類獲得這個方法,由於還有 Visitor7 和 Visitor8 變量。

  • javax.remote.management.rmi.RMIConnectorServer:

    這個類已經添加了兩個字段: CREDENTIALS_FILTER_PATTERN 和 SERIAL_FILTER_PATTERN 。

  • javax.ButtonModel:看,Swing 還在更新!

    ButtonGroup getGroup(): 返回按鈕所屬的組。一般用於單選按鈕,它們在組中是互斥的。

  • javax.plaf.basic.BasicMenuUI:

    Dimension getMinimumSize(JComponent): 返回指定組件適合觀感的最小大小。

JVM 規範改動

這些改動至關小:

  • 4.6節:類文件格式(第99頁)。在方法訪問標誌方面有小的改動。

  • 4.7節:模塊屬性(第169頁)。若是模塊不是 java.base ,則 JDK 10 再也不容許設置 ACC_TRANSITIVE 或 ACC_STATIC_PHASE 。

  • 4.10節:類文件的校驗(第252頁)。dup2 指令已改變了 typesafe form 1 的定義,顛倒了 canSafleyPushList 一節中類型的順序(你須要仔細查看才能發現它)。

  • 5.2節:Java 虛擬機啓動(第350頁)。該描述添加了在建立初始類或接口時可以使用用戶定義的類加載器( bootstrap 類加載器除外)。

對 Java 語言規範的更改

這裏還有一些更改,但主要是爲了支持局部變量類型推斷。

  • 第3.8節:標識符(第23頁)。在忽略了可忽略的字符以後,標識符的等價性如今被考慮了。這彷佛是合乎邏輯的。

  • (第24頁)一個新的 Token,TypeIdentifier,它支持對局部變量類型推斷的新用法,而 var 的使用不是關鍵字,而是一個具備特殊含義的標識符,做爲局部變量聲明的類型。

  • 第4.10.5節:類型預測(第76頁)。這是一個至關複雜的部分,它涉及到捕獲變量、嵌套類以及如何使用局部變量類型推斷。我建議你閱讀規範中的這一部分,而不是試圖解釋它。

  • 第6.1節:聲明(第134頁)。一個反映使用 TypeIdentifier 來支持局部變量類型的推斷的小改動。

  • 第6.5節:肯定名字的含義(第153頁,第158頁和第159頁)。根據類型標識符的使用而更改類類型。

  • 第6.5.4.1:簡單的 PackageOrTypeNames(第160頁)

  • 第6.5.4.2節:合規的 PackageOrTypeNames(第160頁)。這兩種方式都與使用 TypeIdentifier 有細微的變化。

  • 第7.5.3:單靜態導入聲明(第191頁)。這改變了導入具備相同名稱的靜態類型的規則。除非類型是相同的,不然這將成爲一個錯誤,在這種狀況下,重複被忽略。

  • 第7.7.1:依賴(第198頁)。若是你明確聲明一個模塊須要 java.base ,那在必要的關鍵字以後,你就不能再使用修飾符(例如靜態)了。

  • 第8部分:正式參數(第244頁)。接收者參數可能只出如今一個實例方法的 formalparameters 列表,或者是一個內部類的構造函數中,其中內部類沒有在靜態上下文中聲明。

  • 第9.7.4節:註釋可能出現的地方(第335頁)。有一個與局部變量類型推斷相關的變動。

  • 第14.4部分:局部變量聲明語句(第433頁)。實現局部變量類型推斷所需的大量更改。

  • 第14節:加強的 for 語句(第455頁)。這個結構已經更新,包括對局部變量類型推斷的支持。

  • 第14.20.3節:try-with-resources(474頁)。這個結構已經更新,包括對局部變量類型推斷的支持。

最後,第 19 章有多處語法更新,反映了應更多使用 TypeIdentifier 類型標識符,而不只僅是 Identifier 標識符,以支持局部變量類型推斷。

文章有不當之處,歡迎指正,你也能夠關注個人微信公衆號:好好學java,獲取優質視頻教程資源。

相關文章
相關標籤/搜索