I am reading Java 8 book, and it comes with a sample I reproduce:
@FunctionalInterface
public interface Action {
public void perform();
}
An Implementor:
public final class ActionImpl implements Action {
public ActionImpl() {
System.out.println("constructor[ActionIMPL]");
}
@Override
public void perform() {
System.out.println("perform method is called..");
}
}
A caller:
public final class MethodReferences {
private final Action action;
public MethodReferences(Action action) {
this.action = action;
}
public void execute() {
System.out.println("execute->called");
action.perform();
System.out.println("execute->exist");
}
public static void main(String[] args) {
MethodReferences clazz = new MethodReferences(new ActionImpl());
clazz.execute();
}
}
If this is called the following is print into the output:
constructor[ActionIMPL]
execute->called
perform method is called..
execute->exist
Everything is all right but if I use method references not perform message
method is printed! Why is this, am I missing something?
If I use this code:
MethodReferences clazz = new MethodReferences(() -> new ActionImpl());
clazz.execute();
Or this code:
final MethodReferences clazz = new MethodReferences(ActionImpl::new);
This is printed:
execute->called
constructor[ActionIMPL]
execute->exist
No exception message or anything else is printed. I am using Java 8 1.8.25 64bit.
For readers that are studying like me, this is the right running code.
I have created a class the caller.
Because I need to implement a empty method "perform from the Action functional interface" which I need to pass as parameter to class constructor MethodReference
I reference the "constructor of the MethodReferenceCall which is a empty constructor" and I can use it.
public class MethodReferenceCall {
public MethodReferenceCall() {
System.out.println("MethodReferenceCall class constructor called");
}
public static void main(String[] args) {
MethodReferenceCall clazz = new MethodReferenceCall();
MethodReferences constructorCaller = new MethodReferences(MethodReferenceCall::new);
constructorCaller.execute();
}
}
A method reference is similar to lambda expression used to refer a method without invoking it while constructor reference used to refer to the constructor without instantiating the named class.
Constructor Reference is used to refer to a constructor without instantiating the named class. The Constructor reference mechanism is yet another game changing addition by Java 8. You can pass references to constructors as arguments or assign to a target type.
This
MethodReferences clazz = new MethodReferences(() -> new ActionImpl());
does not use method reference, it uses a lambda expression. The functional interface is Action
's
public void perform();
So
() -> new ActionImpl()
gets translated into something similar to
new Action() {
public void perform() {
new ActionImpl();
}
}
Similarly, in
MethodReferences clazz = new MethodReferences(ActionImpl::new);
the ActionImpl::new
, which does use a constructor reference, is translated into something like
new Action() {
public void perform() {
new ActionImpl();
}
}
This ActionImpl::new
does not invoke new ActionImpl()
. It resolves to an instance of the expected type whose functional interface method is implemented as invoking that constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With