Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 constructor method references

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.

Update

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();
    }
}
like image 293
chiperortiz Avatar asked Oct 21 '14 23:10

chiperortiz


People also ask

What is method reference and constructor references in Java 8?

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.

What is constructor reference?

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.


1 Answers

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.

like image 154
Sotirios Delimanolis Avatar answered Sep 26 '22 02:09

Sotirios Delimanolis