Java缺失的特性擴展方法是什麼
什麼是擴充方法
擴充方法,就是能夠直接向現有型別「新增」方法,而無需建立新的派生類型、重新編譯或以其他方式修改現有類型。在呼叫擴展方法時,與呼叫實際在類型中定義的方法相比沒有明顯的差異。
為什麼需要擴充方法
考慮要實現這樣的功能:從Redis 取出包含多個商品ID的字串後(每個商品ID使用英文逗號分隔),先將商品ID進行去重(並且能夠維持元素的順序),最後再使用英文逗號將各個商品ID進行連接。
傳統寫法:
使用 Stream 寫法:
假設在Java 中能實作擴充方法,並且我們為陣列新增了擴充方法 toList(將陣列變成 List) ,為 List 新增了擴充方法 toSet(將 List 變成 LinkedHashSet),為 Collection 新增了擴充方法 join(將集合中元素的字串形式使用給定的連接符號進行連接),那麼我們將可以這樣寫入程式碼:
相信此刻你已經有了為什麼需要擴展方法的答案:
可以對現有的類別庫,進行直接增強,而不是使用工具類別
相比使用工具類,使用類型本身的方法寫程式碼更流暢更舒適
程式碼更容易閱讀,因為是鍊式調用,而不是用靜態方法套娃
在Java 中怎麼實現擴展方法
我們先來問問最近大火的ChatGPT:
#ChatGPT的看法是,在Java中,擴展方法是透過提供的工具類的靜態方法實作的。所以接下來我將介紹一種全新的黑科技:
Manifold
準備條件
Manifold 和Lombok 的工作原理類似,都是透過註解處理器在編譯時進行處理。為了有效地使用Manifold,需要在IDEA中安裝Manifold IDEA插件
然後再在專案pom 的 maven-compiler-plugin 中加入 annotationProcessorPaths:
如果您的專案中使用了Lombok,要將Lombok 也加入 annotationProcessorPaths:
寫擴充方法
JDK 中,String 的 split 方法,使用的是字串作為參數,即 String[] split(String)。我們現在來為 String 新增一個擴充方法 String[] split(char):依照給定的字元進行分割。
基於Manifold,寫擴充方法:
可以發現本質上還是工具類別的靜態方法,但有一些要求:
工具類別需要使用Manifold 的 @Extension 註解
靜態方法中,目標類型的參數,需要使用 @This 註解
#工具類別所在的包名,需要以 extensions.目標類型全限定類別名稱 結尾
—— 用過C# 的同學應該會心一笑,這就是模仿的C# 的擴展方法。
關於第 3 點,之所以有這個要求,是因為 Manifold 希望能快速找到專案中的擴充方法,避免對專案中所有的類別進行註解掃描,提升處理的效率。
具備了擴充方法的能力,現在我們就可以這樣呼叫了:
Amazing!而且你可以發現,System.out.println(numStrs.toString()) 列印的居然是陣列物件的字串形式 —— 而不是陣列物件的位址。瀏覽反編譯後的App.class,觀察到擴充方法的呼叫被取代成了靜態方法呼叫
而陣列的 toString 方法,使用的是Manifold 為陣列定義的擴充方法 ManArrayExt.toString(@This Object array):
[Ljava.lang.String;@511d50c0 什麼的,Goodbye,再也不見~
#因為是在編譯期將擴展方法的調用替換為靜態方法調用,所以使用Manifold 的擴展方法,即使調用方法的對像是 null 也沒有問題,因為處理後的程式碼是把 null 作為參數傳遞到對應的靜態方法。例如,對於Collection進行擴充:
然後呼叫的時候:
java.lang.NullPointerException,Goodbye,再也不見~
陣列擴充方法
我們看到 List 這樣的寫法:@Self 是用來表示被註解的值應該是什麼型,如果是 @Self,也就是 @Self(false),表示被註解的值和 @This 註解的值是同一個型別;@Self(true) 則表示是陣列中元素的型別。
對於物件數組,我們可以看到 toList 方法傳回的就是對應的 List(T 為數組元素的型別):
但如果是原始類型數組,IDEA 指示的回傳值是:
但是我用的是Java 啊,擦除法泛型怎麼可能擁有 List 這麼偉大的函數——所以你只能用原生型別來接收這個回傳值:)
—— 許個願,希望 Project Valhalla 早日GA。
我們常在各個專案中看到,大家先把某個物件包裝成 Optional,然後再進行 filter、map 等。透過 @Self 的型別映射,你可以這樣為 Object 加入一個非常實用的辦法:
那麼任何對象,都會擁有 asOpt() 方法。
比起之前的需要包裝一下的不自然:
你現在可以自然而然的使用 Optional:
#當然,Object 是所有的類別的父類,這樣做是否合適,還是需要謹慎的思考。
擴充靜態方法
我們都知道 Java9 為集合加入了工廠方法:
是不是很眼饞?因為如果用的不是Java9 以上版本(Java8:直接報我身份證就行),你就得用Guava 之類的庫—— 然而 ImmutableList.of 用起來終究是比不上 List.of 這樣的正統來的自然。
沒關係,Manifold 說:「無所謂,我會出手」。基於Manifold 擴展靜態方法,就是在擴展類別的靜態方法上,也加上 @Extension:
然後你就可以欺騙自己已經用上了Java8 之後的版本—— 你發任你發,我用Java8。
BTW,因為 Object 是所有類別的父類,如果你給 Object 新增靜態擴充方法,那麼表示你可以在任何地方直接存取這個靜態方法,而不需要import —— 恭喜你,解鎖了「頂級函數」。
以上是Java缺失的特性擴展方法是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。

PHP適用於Web開發和內容管理系統,Python適合數據科學、機器學習和自動化腳本。 1.PHP在構建快速、可擴展的網站和應用程序方面表現出色,常用於WordPress等CMS。 2.Python在數據科學和機器學習領域表現卓越,擁有豐富的庫如NumPy和TensorFlow。
