首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 閉包與 Lambda 表達式完整指南:從匿名類到函數式編程

     編輯:Java 相關知識

背景:匿名內部類的痛點

Java 8 之前,傳遞行為參數主要靠匿名內部類:

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Running in thread");
    }
}).start();

這帶來三大問題:

  1. 語法冗長:垂直問題——代碼層級嵌套過深
  2. 變量捕獲限制:只能訪問 final 或實際上 final 的局部變量
  3. this 指向混淆:匿名類的 this 指向自身而非外部類

函數式接口:Lambda 的類型基礎

函數式接口:有且僅有一個抽象方法的接口。常見例子:Runnable、Callable、Comparator、ActionListener。可用 @FunctionalInterface 註解標記(編譯器會強制檢查)。

Lambda 表達式語法詳解

(參數列表) -> { 方法體 }
// 或表達式形式(單行,隱式返回)
(參數列表) -> 表達式

示例:

(String s) -> s.length()          // 單參數,表達式體
() -> 43                           // 無參,返回常量
(int x, int y) -> x + y            // 多參數,表達式體
(String s) -> {                    // 語句塊體,需显式 return
    System.out.println(s);
    return s.length();
}

類型推導與簡化規則

  • 參數類型可省略:Comparator<String> c = (s1, s2) -> s1.compareToIgnoreCase(s2);
  • 單參數括號可省略:ActionListener listener = e -> System.out.println(e.getWhen());
  • 方法體單行表達式可省略大括號和 return

變量捕獲:解決匿名類的限制

Lambda 允許捕獲實際上 final的局部變量(無需显式 final),且不允許聲明同名變量遮蓋外部變量:

public void lambdaExample() {
    String variable = "Method Local";
    String nonFinalVariable = "Non-final"; // 未修改,實際上 final
    
    new Thread(() -> {
        // String variable = "Shadow"; // 編譯錯誤:不允許遮蓋
        System.out.println(variable);      // 捕獲外部變量
        System.out.println(this.variable); // this 指向外部類實例
    }).start();
}

方法引用:更簡潔的 Lambda

語法:類名::靜態方法、對象::實例方法、類名::實例方法、類名::new(構造器引用)。

// 靜態方法引用
Arrays.sort(employees, Employee::myCompare);

// 實例方法引用(特定對象)
list.forEach(System.out::println);

// 任意對象實例方法引用
list.sort(String::compareToIgnoreCase);

// 構造器引用
Supplier<List<String>> supplier = ArrayList::new;
Function<String, Employee> creator = Employee::new;

編譯器根據目標類型自動匹配重載方法。

默認方法:接口演進的關鍵

Java 8 允許接口定義默認實現:

interface MyInterface {
    void normalMethod();
    
    default void defaultMethod() {
        System.out.println("Default implementation");
    }
}

解決菱形繼承衝突規則:

  1. 類優先:類中同名方法覆蓋接口默認方法
  2. 子接口可覆蓋、移除或保留父接口默認方法
  3. 多接口衝突:實現類必須显式指定 InterfaceName.super.method()

總結:Java 函數式編程新時代

Lambda 表達式、方法引用、默認方法構成了 Java 8 函數式編程的三大支柱。它們不僅解決了匿名類的語法冗長和語義限制,更為 Stream API、CompletableFuture 等現代 Java 特性奠定了基礎。掌握閉包機制,是寫出簡潔、表達力強的現代 Java 代碼的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved