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:
updateManager.doUpdateForEach(it, DatabaseOperator::updateInfo);
UpdateManager#doUpdateForEach
method expects a RecordIterator
(ok, makes sense), and a FunctionalStuff
FunctionalStuff
has a single method (obviously), that receives 2 paramsdoUpdateForEach
is a method reference (DatabaseOperator::updateInfo
)DatabaseOperator::updateInfo
method receives a single argumenthow 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);
}
});