歡迎光臨
每天分享高質量文章

關於 Java 10 你可能不知道的 5 件事

來自:開源中國 協作翻譯

原文:5 things you didn’t know about Java 10

連結:https://www.ibm.com/developerworks/java/library/j-5things17/index.html

譯者:kevinlinkai, Tocy, 無若, 雪落無痕xdj, 琪花億草

區域性變數型別推斷是有爭議的熱點,但Java 10在JVM中的垃圾收集和容器識別上帶來了可喜的變化。


關於本系列

所以你認為你瞭解Java程式設計? 事實是,大多數開發人員只是浮於Java平臺的錶面上,僅僅為了完成工作而學習。在這個正在進行的系列中,Java技術深入挖掘了Java平臺的核心功能,提出了一些技巧和訣竅,可以幫助你解決即使是最棘手的程式設計挑戰。


Java™開發人員已經習慣了等待新的Java版本釋出,但是新的、高頻率的釋出節奏改變了這一情況。Java 9出現之後僅僅過去6個月,現在Java 10已經在敲門了。再過6個月,我們將迎來Java 11。一些開發人員可能會發現這樣的快速釋出是多餘的,但是新的節奏標志著一個長期需求的改變。


與它的版本號一樣,Java 10提供了10個新特性,本文提供了我認為最重要的5個特性(您可以在Open JDK 10專案頁面上檢視它們)。


1. Java的新版本節奏

從歷史上看,JDK發行的節奏是由大的新特性驅動的。作為最近的例子,Java 8以lambda和流的形式引入了函式式程式設計,而Java 9引入了模組化Java系統。每個新版本都被熱切地期待著,但是次要的修複程式經常束之高閣,等待更大的元件版本被最終確定。Java的進化落後於其他語言。


新的高頻節奏將Java以更小的增量向前推進。在釋出日期準備好的特性將被包括在內,而那些不能被安排在下一個版本中,就在6個月之後。在這個新週期下的第一個Java版本是Java 9,它於2017年10月釋出。Java 10於2018年3月釋出,Java 11將於2018年9月釋出。


作為新節奏的一部分,甲骨文表示,它將只支援每個主要版本,直到下一個主要版本釋出為止。 當Java 11釋出時,Oracle將停止支援Java 10。支援Java版本的開發人員必須每6個月遷移一次主要版本。 不希望或不需要頻繁遷移的開發人員可以使用LTS(長期支援)版本,該版本每三年更新一次。 目前的LTS版本Java 8將在今年秋季釋出Java 11之前得到支援。


2. 區域性變數型別推斷

區域性變數型別推斷是Java 10中最顯著的特性。在進入JDK 10之前,爭論非常激烈,該特性允許編譯器推斷區域性變數的型別,而不是要求程式員明確指定它。


清單1 顯示瞭如何在Java 10之前定義一個String變數型別。


清單1.宣告並分配一個String型別的變數

清單2展示了在Java10中定義與String型別相同的變數


清單2.用區域性變數型別推斷String型別的變數



正如你看到的,唯一的區別就是使用了var保留型別名稱。使用右邊的運算式,編譯器可以將變數名的型別推斷為String。


這看起來有點簡單,讓我們來看一個更加複雜的例子。如果一個變數分配給了呼叫方法的傳回值是怎樣的?在這種情況下,編譯器可以根據方法的傳回型別推斷變數的型別,如清單3所示。


清單3.從傳回型別推斷String型別


使用區域性變數型別

顧名思義,區域性變數型別推斷功能僅適用於區域性變數。 它不能用於定義實體或類變數,也不能用於方法引數或傳回型別。 但是,您可以在類和增強型迴圈中使用var,可以從迭代器中推斷出型別,如清單4所示。


清單4.在迴圈中使用var


使用這種型別的最明顯的原因是為了減少程式碼中的冗長。 看看清單5中的示例。


清單5.很長的型別名稱使得程式碼很長



清單6中的型別宣告是垂直排列的,並且在建構式呼叫的右側每個申明中都會提到一次型別。 想象一下使用這種型別在一些Java框架中常見的長類名的好處。

區域性變數型別的問題

1. var掩蓋了型別


你已經看到了var如何提高程式碼的可讀性,但是從另一方面來看,它也可以掩蓋它。 看看清單7中的示例。

清單7.傳回型別不清楚



在清單7中,我們必須猜測傳回型別。 讓讀者猜測發生了什麼的程式碼是難以維護的。

2. var不能與lambda一起使用


與lambda運算式一起使用時,型別推斷效果不佳,主要原因是編譯器缺少型別資訊。 清單8中的lambda運算式不會被編譯。

清單8.型別資訊不足



在清單8中,編譯器的右邊運算式中沒有足夠的型別資訊來推斷變數型別。 Lambda陳述句必須始終宣告一個顯式型別。

3. var不會與菱形運運算元混在一起


與菱形運運算元一起使用時,型別推斷也不能很好地工作。 看看清單9中的例子。

清單9.使用帶有var的菱形運運算元



親自嘗試一下


想要親自嘗試本地變數型別推斷,您需要下載JDK 10和一個支援它的IDE。 IntelliJ的EAP(Early Access Program)版本具有此支援。 一旦你下載並安裝了它,你可以從本文附帶的GitHub儲存庫中檢出程式碼開始。 你會在那裡找到區域性變數型別推斷的例子。


在程式碼清單9中,books的ArrayList的引數型別是什麼呢?你可能明白你是希望ArrayList儲存一個書的串列,但是編譯器不能推斷出來。反之,編譯器會做的唯一它能做的事情,就是推斷出來這是一個引數是Object型別ArrayList:ArrayList()。


另外一種方法就是在右端運算式中的菱形運運算元中定義具體型別。然後你可以讓編譯器從而推斷出來變數的型別,就像在程式碼清單10中寫的一樣。或者使用另外一種方式,即你必須明確地以傳統方式宣告變數:List books。事實上,你可能更喜歡這種方式,因為它能讓你定義一個抽象型別,並對List介面程式設計:


清單10. 定義出具體型別



3、增加、刪除和棄用

刪除

Java 10刪除了很多工具:


  • 命令列工具javah,可以使用javac -h代替。

  • 命令列選項-X:prof,儘管可以使用jmap工具來訪問分析資訊。

  • 政策工具。


一些從Java1.2開始標記的為已棄用的API也被永久刪除了。包括java.lang.SecurityManager.inCheck欄位和以下方法:

  • java.lang.SecurityManager.classDepth(java.lang.String)

  • java.lang.SecurityManager.classLoaderDepth()

  • java.lang.SecurityManager.currentClassLoader()

  • java.lang.SecurityManager.currentLoadedClass()

  • java.lang.SecurityManager.getInCheck()

  • java.lang.SecurityManager.inClass(java.lang.String)

  • java.lang.SecurityManager.inClassLoader()

  • java.lang.Runtime.getLocalizedInputStream(java.io.InputStream)

  • java.lang.Runtime.getLocalizedOutputStream(java.io.OutputStream)


棄用

JDK 10也棄用了一些API。 java.security.acl包已標記為已棄用,也包括java.security包中包含各種相關的類(Certificate,Identity,IdentityScope,Singer,auth.Policy)。


此外,javax.management.remote.rmi.RMIConnectorServer類中的CREDENTIAL_TYPES被標記為不建議使用。 java.io.FileInputStream和java.io.FileOutputStream中的finalize()方法已被標記為已棄用。所以在java.util.zip.Deflater / Inflater / ZipFileclasses中的finalize()方法也被棄用。

新增和包含


作為Oracle JDK和Open JDK正在進行對接的一部分,Open JDK現在包含Oracle JDK中可用的一部分根證書頒發機構。這些包括Java Flight Recorder和Java Mission Control。此外,JDK 10在java.text,java.time和java.util包的適當位置中增加了對BCP 47語言標記的Unicode擴充套件的增強支援。另一項新功能允許在不執行全域性VM安全點的情況下執行執行緒回呼。這使停止單個執行緒既可行又便宜,而不是要求你停止所有執行緒或不需要任何執行緒。


4.提高容器意識

如果你部署到像Docker這樣的容器,那麼這個功能特別適合你。 現在JVM意識到它正在容器中執行,並查詢容器中可用處理器的數量,而不是查詢主機作業系統。 也可以從外部附加到在容器中執行的Java行程,這使監視JVM行程變得更加容易。


以前,JVM不知道它的容器,並會向主機作業系統詢問活動CPU的數量。 在某些情況下,這會導致JVM過度報告資源,導致多個容器在同一作業系統上執行時出現問題。 在Java 10中,您可以將容器配置為使用主機作業系統的CPU的子集,並且JVM將能夠確定正在使用的CPU數量。 您還可以使用-XX:ActiveProcessorCount標誌明確指明能夠看到的容器化JVM處理器數量。


5.應用程式類資料共享

此特性的用途是提高執行間和多個執行相同程式碼的JVM啟動時間,同時減少記憶體佔用量。 這透過在JVM之間共享關於類的元資料來實現。 JVM的第一次執行收集並歸檔有關它所載入的類的資料。 然後它將資料檔案提供給其他JVM以及該JVM的後續執行,從而節省JVM初始化過程中的時間和資源。 類資料共享實際上已經有一段時間了,但僅限於系統類。 現在這個功能已經擴充套件到包含所有的應用程式類。


結束語

Java10中頭號特性是把Var作為了新的型別名,它可以讓程式碼更加簡潔和清晰。但是,如果使用不謹慎也會掩蓋住原來的含義和意圖。當不明確含義的時候,IDE或許可以幫助你辨別型別,但是在一個IDE中無法讀取所有型別的程式碼。我們經常透過GitHub倉庫、除錯器或者程式碼審查工具線上閱讀程式碼。開發者使用這個新的特性時,務必註意為了將來的讀者和維護人員提高程式碼可讀性。

Java的新版本如此高頻率釋出是一個值得歡迎的改變。在釋出日期,已經準備好的特性必鬚髮布,那些延遲的特性將在短暫的調整之後再下個版本釋出。新的迴圈將加快java的發展行程,那些已經開發完成並且已經列出來的特性,開發者不需要等好多年。


從一個主要版本到下一個主要版本的釋出的支援時間越來越短,這帶來一些合理的擔憂,但是LTS應該可以有效的緩解該問題。釋出疲勞是另一個風險,因為開發者對頻繁的版本更新感到厭煩。總的來說,我認為這是一個積極的行為,在未來很長的一段時間裡,它有助於保證java的活躍度和維持java的發展。


●編號673,輸入編號直達本文

●輸入m獲取文章目錄

推薦↓↓↓

前端開發

更多推薦18個技術類微信公眾號

涵蓋:程式人生、演演算法與資料結構、駭客技術與網路安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。

贊(0)

分享創造快樂