Unexpected Java Functional Interface conversion

pedrorijo91 :

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?

Naman :

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=36709&siteId=1