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

發表於2014-05-04

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

這裡我準備介紹它的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搜下怎麼實現(你很可能用的是Apache.FileUtils)。Java 8給Files類做了一次整容手術,增加了十個新的方法。我最喜歡的一個是walk()方法,它遍歷目錄後會建立出一個惰性的流(檔案系統很大的情況下非常有用)。

增強的隨機數生成

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

Date.toInstant()

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

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

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

如果你覺得有什麼遺漏的或者你覺得我有什麼講的不對的地方,請不吝賜教。下面的評論框就是為這個而準備的:-)

相關文章