來源:codeceo
codeceo.com/article/java-8-top-tips.html
我使用Java 8編碼已經有些年頭,既用于新的應用程式,也用來遷移現有的應用,感覺是時候寫一些我發現的非常有用的“最佳實踐”,
我個人并不喜歡“最佳實踐”這個說法,因為它意味著“一刀切”的解決方案,而編碼不可能是這樣的作業方式——我們需要親自去發現什么樣的解決方案才是有效的,
但是我發現了一些Java 8代碼中可以幫助我們的一些選擇,讓我們一起來看看吧,
1.Optional
Optional是一個嚴重被低估的功能,并且有潛力洗掉很多困擾我們的NullPointerExceptions,這在代碼邊界中(要么是正在使用的API,要么是正在暴露的API)特別有用,因為它允許你和你的呼叫代碼來推理所期待的東西,
然而,不加思考和設計就應用Optional可能會導致影響大量的類,并可能導致可讀性更差,下面是一些關于如何高效使用Optional的技巧,
Optional應該只用于回傳型別
……不是引數,也不是欄位,幸運的是,IntelliJ IDEA的讓你打開檢查來查看是是否遵循這些建議,

Optional值應在遇到它們的地方中處理,IntelliJ IDEA的建議會防止代碼Optional泄漏,所以請記得在你發現Optional的地方處理它,迅速采取行動,

不應該簡單呼叫get()
Optional的功能是表達這個值可能是空的,并讓你應對這種情況,因此,在對它做任何事情之前一定要檢查是否有一個值,只是簡單得呼叫get()而不先檢查isPresent()在某些時候可能會導致空指標,幸運的是,IntelliJ IDEA也有檢查可以提醒你這一點,

可能有更優雅的方式
結合了get()的isPresent()當然會很贊…

……但也有更優雅的解決方案,你可以使用orElse在萬一是空值的情況下給一個替代方案,

……或者你可以使用orElseGet說明在值為空的情況下呼叫哪個方法,這似乎與上面的例子相同,但supplier方法將只在需要的時候呼叫,因此,如果這是一種昂貴的方法,那么使用lambda會有更佳性能,推薦閱讀:JDK8新特性之Stream流,

2.使用Lambda運算式
Lambda運算式是Java 8的主要特點之一,即使你還沒有使用Java 8,你現在可能已經對它們有了基本的了解,它們是用Java編程的一種新的方式,并且什么是“最佳實踐”還不明顯,下面是我喜歡遵循的一些指引,
保持簡短
函式式程式員與較長的lambda運算式相處會更愉快,但那些淫浸于Java多年的人會發現保持lambda運算式為區區幾行代碼更容易,你甚至可能更愿意將其限制到一行代碼,并且你可以輕松重構較長的運算式為一個方法,

這些甚至可能會成為方法參考,方法參考一開始會覺得有點陌生,但實際上堅持方法參考是有價值的,因為它們在某些情況下有助于可讀性,后面我會討論到這一點,

明確
型別資訊缺少lambda運算式,所以你可能會覺得包含型別資訊用于引數會很有用,

正如你所見,這回變得相當笨拙,所以我更喜歡給引數取一個有用的名字,當然,不管你有沒有這么做,IntelliJ IDEA可以讓你看到引數得型別資訊,

甚至是lambda所代表的函式式介面:

3.針對Lambda運算式設計
我認為lambda運算式有點像泛型——和泛型一起,我們經常使用它們(例如,添加型別資訊到List< >),但最好我們可以設計一種方法或一個具有泛型型別(例如Person< T >)的類,
同樣的,當使用類似于Streams API的東西時,我們會傳遞lambda運算式,但更好的是創造一個需要lambda引數的方法,推薦閱讀:JDK8新特性之Lambda運算式,
但是,如果你發現自己處于這類情況下,下面有一些超棒的技巧,
IntelliJ IDEA可以幫你引進函式式引數
這讓你可以在有人將傳遞一個lambda而非Object的地方創建一個引數,此功能的好處是,它表明,現有函式式介面匹配規格說明,

這會導致…
使用現有的函式式介面
隨著開發人員越來越熟悉Java 8代碼,我們就能知道當使用如Supplier和 Consumer的介面時,會發生什么,以及創建一個本地的ErrorMessageCreator(舉個例子)可能會造成混亂,而且浪費,看看這個函式包了解一下哪些已經是可用的,推薦閱讀:JDK8新特性之函式式介面,
添加@FunctionalInterface到函式式介面
如果你確實需要創建自己的函式式介面,那么就這樣用此注釋標記,這似乎沒有太大的作用,但IntelliJ IDEA會告訴你,在你的介面不能匹配用于函式式介面的例外的時候,當你沒有指定要覆寫的方法時,它會標志:

當你指定了太多方法的時候,它會標志:

并且如果你應用它到一個類而不是介面時,它會警告你:

lambda運算式可用于帶有一個單一抽象方法的任何介面,但它們不能用于符合相同標準的抽象類,似乎不合邏輯,但就是這樣,
4.Stream
Stream API是Java 8另一個大特點,并且我認為我們還真的不知道這對我們的編碼方式會產生多大的改變,下面是我發現的一些有用的東西
排隊點運算子
我個人更喜歡排隊我的流操作,當然,你沒有必要這樣,當我發現這樣做對我有幫助:
-
一目了然地看到我有哪些操作
-
除錯更容易(雖然IntelliJ IDEA確實提供了對一行中的任意多個lambda運算式設定斷點的能力,但是拆分到不同的行會變得更簡單)
-
當我測驗東西的時候注釋操作
-
輕松插入peek()用于除錯或測驗

此外,在我看來,它更整潔,如果我們按照這個模式,在減少代碼行數方面我們并沒有增加很多,
你可能需要調整格式設定以排列點運算子,

使用方法參考
是的,確實需要一段時間來適應這個奇怪的語法,但是,如果使用得當,它確實可以增加可讀性,請看:

與(相對)新的Objects類上的輔助方法相比較:

后者的代碼對于哪些值是要保存的更加明確,當lambda可以被折疊到方法參考的時候,IntelliJ IDEA通常會讓你知道,

當遍歷一個集合時,在可行的情況下使用Streams API
…或者新的集合方法,如forEach,IntelliJ IDEA給你建議是:

一般使用Streams API比回圈和if陳述句的組合更加明確,例如:

IntelliJ IDEA建議這可重構為:

我所做的性能測驗表明這種重構令人驚訝——并不總是可預測性能是保持不變,改善還是變得更糟,與往常一樣,如果性能在應用程式中是關鍵,那么在交付一種風格到另一種之前衡量它,
遍歷陣列時使用回圈
但是,使用Java 8并不一定意味著你必須到處使用流和新的集合方法,IntelliJ IDEA會建議轉換成流,但是,這并不意味著你必須回答“yes”(記得檢查是可以抑制或關閉的),
特別是,遍歷原始型別的小型陣列幾乎肯定會用,以獲得更好的性能回圈,很可能(至少對于Java開發人員是新的流)更具可讀性,

與任何技巧一樣,規則并不是一成不變的,但你應該決定是盡可能地使用Streams API,還是依然對一些操作使用回圈,總之,要一致,更多 JDK 新特性請在Java技術堆疊公眾號后臺回復:新特性_,
推薦去我的博客閱讀更多:
1.Java JVM、集合、多執行緒、新特性系列教程
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
4.Java、后端、架構、阿里巴巴等大廠最新面試題
覺得不錯,別忘了點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/174983.html
標籤:Java
