Home > database >  Calling method reference using lambda (:: operator)
Calling method reference using lambda (:: operator)

Time:11-04

I have seen some approaches as shown below:

calling like this:

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));
}


or using method references:

private static void addCustomerTransaction() {
  customerInput(Bank::addCustomerTransaction);
}

private static void addCustomer() {
  customerInput(Bank::addCustomer);
}

I read that code like that: When calling addCustomerTransaction() method, it calls the customerInput method by passing Bank class's addCustomer method. But it seems to be a recursive call. SO, what is the meaning and could you pls give a brief example?

Thanks in advance.

CodePudding user response:

No, this won't be a recursive call since Bank::addCustomerTransaction won't refer to private static void addCustomerTransaction() but to a method with the same name and a fitting signature. I'll provide a simple answer but please look for a proper tutorial on this for details.

Let's assume the parameter for customerInput() is an interface that has a method like this:

void takeInput(Bank bank, String branchName, String customerName, Transaction transaction);

Now you could pass any method reference that matches this signature and the same method resolution rules apply that Java uses for normal method calls, i.e. if you have 2 methods void foo(int x) and void foo(long x) and a call foo(2) the compiler will need to determine whether you mean to call the 1st or 2nd method (here the 1st method would be chosen because 1 is an int literal).

With those rules in place, how does the compiler select the method in your case?

Let's assume we have the following class:

class Bank {
   void addCustomerTransaction(String branchName, String customerName, Transaction transaction) { ... }

   static void addCustomerTransaction() {
     customerInput(Bank::addCustomerTransaction);
   }
}

Why isn't this a recursive call?

Because void addCustomerTransaction() doesn't match the signature required for void takeInput(Bank, String, String, Transaction) at all.

But why does the instance method void addCustomerTransaction(String, String, Transaction) match?

That's because instance methods implicitly get a first parameter which is a reference to the instance (i.e. the this reference), so to the compiler that method looks like this (internally there is no difference between static and instance methods):

 void addCustomerTransaction(Bank, String, String, Transaction)

Now this matches the required signature and hence the method can be called.

To prove this, try to add a static method with the same signature:

 static void addCustomerTransaction(Bank bank, String branchName, String customerName, Transaction transaction) { ... }

Now the compiler can't decide whether to use the static method or the instance method and it will tell you so.

  • Related