[英]Calling method reference using lambda (:: operator)
我已經看到了一些方法,如下所示:
像這樣調用:
private static void addCustomerTransaction() {
customerInput((bank, branchName, customerName, transaction) ->
bank.addCustomerTransaction(branchName, customerName, transaction));
}
private static void addCustomer() {
customerInput((bank, branchName, customerName, transaction) ->
bank.addCustomer(branchName, customerName, transaction));
}
或使用方法引用:
private static void addCustomerTransaction() {
customerInput(Bank::addCustomerTransaction);
}
private static void addCustomer() {
customerInput(Bank::addCustomer);
}
我看這樣的代碼:當調用addCustomerTransaction()
方法中,它調用customerInput
通過傳遞方法Bank
類的addCustomer
方法。 但這似乎是一個遞歸調用。 所以,這是什么意思,你能舉一個簡單的例子嗎?
提前致謝。
不,這不會是遞歸調用,因為Bank::addCustomerTransaction
不會引用private static void addCustomerTransaction()
而是引用具有相同名稱和合適簽名的方法。 我將提供一個簡單的答案,但請查找有關此問題的適當教程以獲取詳細信息。
讓我們假設customerInput()
的參數是一個具有如下方法的接口:
void takeInput(Bank bank, String branchName, String customerName, Transaction transaction);
現在您可以傳遞與此簽名匹配的任何方法引用,並且 Java 用於普通方法調用的相同方法解析規則適用,即如果您有 2 個方法void foo(int x)
和void foo(long x)
以及調用foo(2)
編譯器將需要確定您是要調用第一個方法還是第二個方法(這里將選擇第一個方法,因為1
是一個int
字面量)。
有了這些規則,編譯器如何在您的情況下選擇方法?
假設我們有以下類:
class Bank {
void addCustomerTransaction(String branchName, String customerName, Transaction transaction) { ... }
static void addCustomerTransaction() {
customerInput(Bank::addCustomerTransaction);
}
}
為什么這不是遞歸調用?
因為void addCustomerTransaction()
根本不匹配void takeInput(Bank, String, String, Transaction)
所需的簽名。
但是為什么實例方法void addCustomerTransaction(String, String, Transaction)
匹配呢?
那是因為實例方法隱式地獲取第一個參數,它是對實例的引用(即this
引用),所以對於編譯器來說,該方法看起來像這樣(靜態方法和實例方法在內部沒有區別):
void addCustomerTransaction(Bank, String, String, Transaction)
現在這匹配所需的簽名,因此可以調用該方法。
為了證明這一點,嘗試添加一個具有相同簽名的靜態方法:
static void addCustomerTransaction(Bank bank, String branchName, String customerName, Transaction transaction) { ... }
現在編譯器不能決定是使用靜態方法還是實例方法,它會告訴你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.