使用 lambda (:: 运算符) 调用方法参考
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()
方法时,它通过Bank
class的addCustomer
方法调用customerInput
方法.但它似乎是一个递归调用。 SO,什么意思,能举个简单的例子吗?
提前致谢。
不,这不会是递归调用,因为 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
文字)。
有了这些规则,编译器如何select你的方法?
假设我们有以下 class:
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
引用),所以到compiler 该方法看起来像这样(在内部静态和实例方法之间没有区别):
void addCustomerTransaction(Bank, String, String, Transaction)
现在这与所需的签名匹配,因此可以调用该方法。
为了证明这一点,尝试添加一个具有相同签名的静态方法:
static void addCustomerTransaction(Bank bank, String branchName, String customerName, Transaction transaction) { ... }
现在编译器无法决定是使用静态方法还是实例方法,它会告诉你。
我见过一些方法,如下所示:
这样调用:
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()
方法时,它通过Bank
class的addCustomer
方法调用customerInput
方法.但它似乎是一个递归调用。 SO,什么意思,能举个简单的例子吗?
提前致谢。
不,这不会是递归调用,因为 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
文字)。
有了这些规则,编译器如何select你的方法?
假设我们有以下 class:
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
引用),所以到compiler 该方法看起来像这样(在内部静态和实例方法之间没有区别):
void addCustomerTransaction(Bank, String, String, Transaction)
现在这与所需的签名匹配,因此可以调用该方法。
为了证明这一点,尝试添加一个具有相同签名的静态方法:
static void addCustomerTransaction(Bank bank, String branchName, String customerName, Transaction transaction) { ... }
现在编译器无法决定是使用静态方法还是实例方法,它会告诉你。