Unexpected Java Functional Interface conversion

  • A+

I have the following piece of code, that uses java Functional Interfaces, that compiles, but it's not clear why does it compile:

public class App {      public static void main(String[] args) throws Exception {          final RecordIterator it = new RecordIterator<MyRecord>();          final UpdateManager updateManager = new UpdateManager();         updateManager.doUpdateForEach(it, DatabaseOperator::updateInfo);      } }  class UpdateManager {      public void doUpdateForEach(final RecordIterator recordIterator,                                 final FunctionalStuff<MyRecord> updateAction) throws Exception {          updateAction.execute(new DatabaseOperator(), new MyRecord());      }  }  class RecordIterator<E> {  }  @FunctionalInterface interface FunctionalStuff<T> {      void execute(final DatabaseOperator database, final T iterator) throws Exception;  }  class DatabaseOperator {      public void updateInfo(final MyRecord r) {      }  }  class MyRecord {  } 

So, my confusion is inside of the main method:

  • the last line of the main method is updateManager.doUpdateForEach(it, DatabaseOperator::updateInfo);
  • the UpdateManager#doUpdateForEach method expects a RecordIterator (ok, makes sense), and a FunctionalStuff
  • FunctionalStuff has a single method (obviously), that receives 2 params
  • The second argument of the doUpdateForEach is a method reference (DatabaseOperator::updateInfo)
  • The DatabaseOperator::updateInfo method receives a single argument

how does this compiles? How is the DatabaseOperator::updateInfo method reference converted into the functional interface? Am I missing something obvious? Or is some corner case of functional interfaces?


How is the DatabaseOperator::updateInfo method reference converted into the functional interface?

The effective lambda representation of your method reference is :

updateManager.doUpdateForEach(it, (databaseOperator, r) -> databaseOperator.updateInfo(r)); 

which is further representation of anonymous class:

new FunctionalStuff<MyRecord>() {     @Override     public void execute(DatabaseOperator databaseOperator, MyRecord r) throws Exception {         databaseOperator.updateInfo(r);     } }); 


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: