Java中將方法作為引數傳遞5種方式

banq發表於2024-06-16

在 Java 中,我們可以使用函數語言程式設計概念將一個方法作為引數傳遞給另一個方法,具體來說是使用 lambda 表示式、方法引用和函式介面。在本教程中,我們將探討將方法作為引數傳遞的幾種方法。

1、使用介面和匿名內部類
在 Java 8 之前,我們依賴介面和匿名內部類將方法作為引數傳遞。下面是一個示例來說明這種方法:

interface Operation {
    int execute(int a, int b);
}

我們定義一個名為Operation 的介面,該介面只有一個抽象方法execute()。此方法接受兩個整數作為引數並返回一個整數。任何實現此介面的類都必須提供execute()方法的實現。

接下來,我們建立一個名為performOperation()的方法來接收兩個整數引數和一個Operation例項:

int performOperation(int a, int b, Operation operation) {
    return operation.execute(a, b);
}

在這個方法中,我們呼叫operation.execute(a, b)。這行程式碼呼叫作為引數傳遞的Operation例項的execute()方法。

然後我們呼叫performOperation()方法並傳遞三個引數:

int actualResult = performOperation(5, 3, new Operation() {
    @Override
    public int execute(int a, int b) {
        return a + b;
    }
});

在performOperation()方法中,使用匿名內部類建立Operation介面的新例項。此類沒有名稱,但它動態地提供了對execute()方法的實現。

在匿名內部類中,重寫了execute()方法。在本例中,它只是將兩個整數a和b相加,然後返回兩個整數的和。

最後,讓我們使用斷言驗證我們的實現,以確保結果符合預期:

assertEquals(8, actualResult);

2.使用 Lambda 表示式
在 Java 8 中,lambda 表示式使將方法作為引數傳遞更加優雅和簡潔。以下是我們如何使用 lambda 實現相同的功能:

@FunctionalInterface
interface Operation {
    int execute(int a, int b);
}

我們定義一個介面Operation,並使用@FunctionalInterface註釋來指示該介面只有一個抽象方法。

接下來,我們呼叫performOperation()方法並傳入兩個整型引數和一個Operation介面的例項:

int actualResult = performOperation(5, 3, (a, b) -> a + b);

對於第三個引數,我們傳遞的不是匿名內部類,而是 lambda 表示式(a, b) -> a + b,它表示Operation功能介面的一個例項。

我們應該得到相同的結果:

assertEquals(8, actualResult);

與匿名內部類相比,使用 lambda 表示式簡化了語法並使程式碼更具可讀性。

3. 使用方法引用
Java 中的方法引用提供了一種將方法作為引數傳遞的簡化方法。它們充當呼叫特定方法的 lambda 表示式的簡寫。讓我們看看如何使用方法引用實現相同的功能。

我們定義一個名為add()的方法,它接受兩個整數a和b作為引數並返回它們的和:

int add(int a, int b) {
    return a + b;
}

此方法只是將兩個整數相加並返回結果。然後,使用語法object::methodName或  ClassName::methodName將該方法作為引用傳遞:

int actualResult = performOperation(5, 3, FunctionParameter::add);
assertEquals(8, actualResult);

此處,FunctionParameter::add指的是FunctionParameter類中的add()方法 。它允許我們將add()方法定義的行為作為引數傳遞給另一個方法,在本例中為performOperation()方法。

此外,在performOperation()方法中,add()方法引用被視為Operation功能介面的一個例項,該介面具有單個抽象方法execute()。

4. 使用函式類
除了方法引用和 lambda 表示式之外,Java 8 還引入了java.util.function包,為常用操作提供了函式式介面。其中,BiFunction是一個函式式介面,表示一個有兩個輸入引數和一個返回值的函式。下面我們來探索如何使用BiFunction實現類似的功能。

首先,我們建立executeFunction()方法,該方法接受BiFunction<Integer, Integer, Integer>作為第一個引數。這意味著它接收一個以兩個Integer值作為輸入並返回一個Integer 的函式:

int executeFunction(BiFunction<Integer, Integer, Integer> function, int a, int b) {
    return function.apply(a, b);
}

apply ()方法用於將函式應用於其兩個引數。接下來,我們可以使用 lambda 表示式建立BiFunction的例項,並將其作為引數傳遞給executeFunction()方法:

int actualResult = executeBiFunction((a, b) -> a + b, 5, 3);

此 lambda 表示式(a, b) -> a + b表示一個對其兩個輸入求和的函式。整數5和3分別作為第二和第三個引數傳遞。

最後,我們使用斷言來驗證我們的實現是否按預期工作:

assertEquals(8, actualResult);

5. 使用可呼叫類
我們還可以使用Callable將方法作為引數傳遞。Callable介面是java.util.concurrent包的一部分,表示返回結果並可能引發異常的任務。這在併發程式設計中特別有用。

讓我們探索如何使用Callable將方法作為引數傳遞。首先,我們建立接受Callable<Integer>作為引數的executeCallable()方法。這意味著它接收一個返回Integer的任務:

int executeCallable(Callable<Integer> task) throws Exception {
    return task.call();
}

call ()方法用於執行任務並返回結果。它可能會引發異常,因此我們需要適當處理它。我們可以使用 lambda 表示式或匿名內部類定義Callable任務。這裡,為了簡單起見,我們使用 lambda 表示式:

Callable<Integer> task = () -> 5 + 3;

這個 lambda 表示式表示計算5和3之和的任務。然後我們可以呼叫executeCallable()方法並將Callable 任務作為引數傳遞:

int actualResult = executeCallable(task);
assertEquals(8, actualResult);

使用Callable將方法作為引數傳遞提供了一種替代方法,這在併發程式設計場景中特別有用。

相關文章