Java 8中你可能沒用過的10個特性

lambda表達式,lambda表達式,還是lambda表達式。一提到Java 8就只能聽到這個,但這不過是其中的一個新功能而已,Java 8還有許多新的特性——有一些功能強大的新類或者新的用法,還有一些功能則是早就應該加到Java裏了。

Java 8中你可能沒用過的10個特性

這裏我準備介紹它的10個非常值得了解的新特性。總會有一款適合你的,開始來看下吧。

Java 8中你可能沒用過的10個特性

  default方法

這是Java語言的一個新特性,現在接口類裏可以包含方法體(這就是default方法)了。這些方法會隱式的添加到實現這個接口的每個子類中。

這使得你可以在不破壞代碼的前提下擴展原有庫的功能。它絕對是個利器。但從另一個方面來說,這使得接口作爲協議,類作爲具體實現的界限開始變得有點模糊。但好處就是,它通過一個很優雅的方式使得接口變得更智能,同時還避免了代碼冗餘,並且擴展類庫。不好的地方就是,我估計很快就會看到有在接口方法裏獲取this引用然後強制轉化成某個具體類型的寫法了。

  終止進程

一旦啓動外部進程的話,當這個進程崩潰,掛起,或者CPU到達100%的時候,你就得回來擦屁股了。Process類現在增加了兩個新的方法,可以來教訓下那些不聽話的進程了。

第一個是isAlive()方法,有了它你可以判斷進程是否還活着。第二個方法則更加強大,它叫destroyForcibly(),你可以用它來強制的殺掉一個已經超時或者不再需要的進程。

  StampedLock

提到這個不禁有點小激動。沒有人會喜歡在代碼中使用同步。用了它肯定會降低程序的吞吐量,更糟糕的話還會導致進程掛起。儘管這樣,有時候你卻不得不選擇它。

當多個進程訪問一個資源的時候,有多種方法可以進行同步。其中用得最多的一種是ReadWriteLock以及基於它的幾種實現。它通過阻塞寫線程的方式來允許多個線程併發的讀,這樣減少了線程之間的競爭。聽起來還不錯,但實際上這個鎖實在是太太太慢了,尤其是當有許多寫線程的時候。

因此Java 8引入了一個新的讀寫鎖,叫做StampedLock。它不僅更快,同時還提供了一系列強大的API來實現樂觀鎖,這樣如果沒有寫操作在訪問臨界區域的話,你只需很低的開銷就能獲取到一個讀鎖。訪問結束後你可以查詢鎖來判斷這期間是否發生了寫操作,如果有的話再選擇進行重試,升級鎖,或者放棄這個操作。

這的確是一個非常強大的工具,它本身就值得專門花一篇文章來介紹。這個新玩意兒讓我感到非常激動和興奮,它真的'是太棒了。

  併發計數器

這是多線程程序會用到的另一個小工具。它提供了簡單高效的新接口來實現多線程的併發讀寫計數器的功能,和AtomicInteger比起來,它要更快一些。相當讚的工具。

  Optional

不好,又有空指針了,這是所有Java開發人員的痛處。這估計是有史以來最常見的異常了,至少是1965年以來。

Java 8借鑑了Scala和Haskell,提供了一個新的Optional模板,可以用它來封裝可能爲空的引用。這絕不是終結空指針的銀彈,更多隻是使API的設計者可以在代碼層面聲明一個方法可能會返回空值,調用方應該注意這種情況。正因爲這個,這隻對新的API有效,前提是調用方不要讓引用逃逸出封裝類,否則的話引用可能會在外面被不安全的廢棄掉。

我對這個新的特性真的是又愛又恨。一方面,空指針是一個大問題,只要能解決這個問題的東西我都歡迎。但另一方面,我對它是否能擔此重任執懷疑的態度。這是由於使用它的話需要全公司的集體努力,短期內很難會有見效。除非大力地推廣,否則很可能會功虧一簣。

 萬物皆可註解

還有一個小的改進就是現在Java註解可以支持任意類型了。之前只有像類和方法聲明之類的才能使用註解。在Java 8裏面,當類型轉化甚至分配新對象的時候,都可以在聲明變量或者參數的時候使用註解。這是Java爲了更好地支持靜態分析及檢測工具(比如FireBug)而做的工作中的一部分。這是個很不錯的特性,但是和Java 7的invokeDynamic一樣,它的真正價值取決於社區以後如何去使用它。

  數值溢

這些方法早就該出現在Java的核心類庫裏了。我有個癖好就是去測試整型超出2^32時溢出的情況,搞出一些噁心的隨機BUG來(怎麼會得到這麼奇怪的一個值?)。

同樣的,這也不是什麼銀彈,只不過是提供了一組函數,這樣你在使用+/*操作符進行數值操作的時候,如果出現了溢出,會拋一個異常。如果我可以決定的話,我會把它作爲JVM的默認模式,顯式的標明函數會出現數值溢出。

  目錄遍歷

遍歷目錄樹這種事通常都得上Google搜下怎麼實現(你很可能用的是Utils)。Java 8給Files類做了一次整容手術,增加了十個新的方法。我最喜歡的一個是walk()方法,它遍歷目錄後會創建出一個惰性的流(文件系統很大的情況下非常有用)。

  增強的隨機數生成

現在經常都在討論密碼或者密鑰容易遭受攻擊的事。程序的安全性是項很複雜的工程,並且很容易出錯。這就是我爲什麼喜歡這個新的nstanceStrong()方法的原因,它能自動選擇出當前JVM可用的最佳的隨機數生成器。這樣減少了獲取失敗的機率,同時也避免了默認的弱隨機數生成器可能會導致密鑰或者加密值容易被黑客攻破的問題。

  stant()

Java 8引入了一個新的日期API。這不難理解,因爲現有的這個實在是太難用了。實際上Joda一直以來都是Java日期API的首選。不過儘管有了新的API,但仍有一個嚴重的問題——大量的舊代碼和庫仍然在使用老的API。

並且我們還知道這種現狀仍將繼續存在下去。到底該怎麼做呢?

Java 8很優雅的解決了這個問題,它給Date類增加了一個新的方法toInstant(),它可以將Date轉化成新的實現。這樣你馬上就可以切換到新的API,儘管現有的代碼還在使用老的日期API(並且在可預見的未來仍將繼續這樣)。