整理 Effective Java 書中 Item 43: Prefer method references to lambdas 心得筆記

主旨

Java 8 推出 Lambda 表達式後,大大減少了匿名類別帶來的冗長語法。不過其實 Java 還有更簡潔的選擇,那就是「方法參考」(Method Reference)。這種語法讓我們可以直接把現有的方法當作函式物件來用,省去命名參數和撰寫邏輯的麻煩。本篇將說明方法參考的用法、優勢,以及在什麼情況下優先使用。

範例比較:Lambda vs 方法參考

假設我們有一個字串出現次數的統計程式:

map.merge(key, 1, (count, incr) -> count + incr);

這段用 Lambda 寫的,其實就只是在做加總,沒什麼特殊邏輯。Java 的 Integer 類別本來就有個 sum() 方法,我們可以直接用方法參考:

map.merge(key, 1, Integer::sum);

這樣一來不但程式碼更短,也更直接表達我們的意圖:用 Integer.sum() 來合併數值。

劃重點:什麼情況適合用方法參考?

方法參考可分為以下五種類型:

類型範例對應的 Lambda 寫法
靜態方法參考Integer::parseInts -> Integer.parseInt(s)
綁定實例方法參考someInstant::isAftert -> someInstant.isAfter(t)
未綁定實例方法參考String::toLowerCases -> s.toLowerCase()
類別建構子參考TreeMap::new() -> new TreeMap<>()
陣列建構子參考int[]::newlen -> new int[len]

方法參考比 Lambda 更適合的時機:

  • 邏輯已經封裝在現有方法中,無需重寫
  • Lambda 表達式很短但參數命名沒有加值效果
  • 你想把邏輯抽成一個具名方法來提升可讀性,然後用方法參考來取代原本冗長的 Lambda。

真實世界範例:取代冗長的策略實作

假設有一個 Service 需要執行某段邏輯:

service.execute(() -> action());

如果你改成這樣:

service.execute(GoshThisClassNameIsHuge::action);

會發現方法參考反而不如 Lambda 簡潔。因此在方法本身就很短、參數簡單明瞭時,Lambda 會更合適。

又比如這種回傳自身參數的 Function:

Function<String, String> identity = x -> x;
// 比 Function.identity() 還清楚

小結

使用方法參考的原則其實很簡單:

  • 更短更清楚時就用方法參考
  • 否則用 Lambda
  • Lambda 太長或太難讀的話,抽成具名方法再用方法參考

記住這個原則,可以幫你在寫 Java 8+ 的程式碼時保持簡潔又具表達力。畢竟我們寫的是給人看的,不是給編譯器看的。