Java 8 引入 Lambda 表達式被稱為「函數式編程來到 Java」。但 Java 真正成為函數式語言了嗎?本文從類型系統演進、函數式核心特徵、Java 8 實現機制三個維度深度剖析。
filter → map → reduce 管道式處理,而非命令式迴圈
強制純函數式 (Haskell, Clojure)
↓ 允許可變但鼓勵函數式 (Scala, F#, Kotlin)
↓ 支援函數式特性但非核心 (Java 8+, C#, Python, JS)
↓ 傳統命令式 (Java 7-, C, C++ 早期標準)
| 版本 | 關鍵特性 | 類型系統影響 |
|---|---|---|
| 1.0 | 類、接口、數組、基本類型 | 標稱類型:每個類型必須有名字 |
| 5.0 | 泛型、枚舉、注解 | 參數化類型,擦除實現,編譯期/運行期類型系統分離 |
| 7.0 | 菱形語法、多捕獲、MethodHandle | 類型推斷微改進,為 Lambda 鋪路 |
| 8.0 | Lambda、Stream、默認方法、類型注解 | 函數類型以函數式接口形式建模,仍屬標稱類型 |
// 寫法
Runnable r = () -> System.out.println("Hello");
// 編譯器視為
Runnable r = new Runnable() {
@Override public void run() { System.out.println("Hello"); }
};
// 關鍵差異:類型由目標類型推斷(Target Typing)
// 無目標類型上下文 → 編譯錯誤
// Object o = () -> {}; // 錯誤:Object 非函數式接口
{def bar: String} 直接描述結構Predicate, Function, Consumer, Supplierfilter/map/flatMap/reduce/collect 管道操作String::valueOf, obj::method, Class::newJava 8 並未追求純粹,而是提供「恰到好處」的函數式工具箱:
parallelStream() 一鍵利用多核若項目需純粹函數式:Scala(OOP+FP 混合)、Kotlin(現代實用)、Clojure(Lisp 方言、不可變持久化數據結構)。它們與 Java 無縫互操作,可按模塊選擇。