-1

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.

  • 1
    `customerInput(Bank::addCustomerTransaction)` is basically translated to `(bank, branchName, customerName, transaction) -> bank.addCustomerTransaction(branchName, customerName, transaction))` as they have the same signature. The catch is that the first parameter `bank` is the bank instance and `addCustomerTransaction(String branchName, String customerName, Transaction transcation)` (guessed the param types) actually has an implicit first `this` parameter which is the bank. So this method is different from the static `addCustomerTransaction()`. – Thomas Oct 28 '21 at 15:49
  • Here's also a quick find for relevant topic that will hopefully explain different styles of lambdas and method references in Java: https://www.geeksforgeeks.org/method-references-in-java-with-examples/ – M. Prokhorov Oct 28 '21 at 16:01
  • @Thomas Thanks a lot, but could not understand completely. Maybe my example is not a proper example. Could you pls explain by using a proper example as an answer? –  Nov 01 '21 at 18:09
  • @M.Prokhorov Seems a useful page, thanks a lot. –  Nov 01 '21 at 18:10

1 Answers1

0

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.

Thomas
  • 87,414
  • 12
  • 119
  • 157
  • Thank you very much for these wonderful explanations. For further reading, could you please give me some reference tutorial so that I can read and make practice to get better idea. –  Nov 03 '21 at 17:48
  • And of course I would be grateful if you also vote up to the question –  Nov 03 '21 at 17:49
  • @Jonathan I find this article quite helpful and easy to read: https://www.baeldung.com/java-method-references But of course there are many others and you might need some experimentation to gain experience. Some more links: https://javadevcentral.com/default-method-resolution-rules, https://www.codementor.io/@eh3rrera/using-java-8-method-reference-du10866vx and a of couse the specification will help: https://docs.oracle.com/javase/specs/jls/se17/html/jls-15.html#jls-15.12 (method resolution), https://docs.oracle.com/javase/specs/jls/se17/html/jls-15.html#jls-15.13 (method references) – Thomas Nov 04 '21 at 06:53
  • **You rock!..** I will read all of them, thanks a lot again and regards... –  Nov 04 '21 at 10:05