Lambda: callable variable triggered by Runnable instance

Just found the strange and interesting behavior of the Lambda.

Let's have the following class:

private class Task implements Runnable {
    @Override
    public void run() {
       // something to process
    }
}

      

The following statement will compile and run:

Callable task = Task::new;

      

Can anyone explain why this is possible?

EDIT

Based on the answers below, check the following statements:

1.

ExecutorService executor = Executors.newSingleThreadExecutor(); executor.submit(Task::new);

2.

ExecutorService executor = Executors.newSingleThreadExecutor(); executor.submit(new Task());

At first glance it seems the same, but in fact it does a completely different thing.

What is happening here is exactly the above situation.

The reason is that it ExecutorService

has two methods:

submit(Runnable); submit(Callable);

So, using the code from 1., the executor will process the internal stream on it:

new Task()

The version from 2. will actually call the method submit(Runnable)

and the code from Task.run

.

Conclusion: be careful with Lambdas :)

+3


source to share


2 answers


The callable is not instantiated Runnable

, it is initialized by a method reference to the constructor Task

that will be issued Runnable

on execution.

In other words, if you do this Callable

, it will return a new object Task

that hasn't been started yet. What Task

implements Runnable

is really completely irrelevant.



It would be clearer if you weren't using a raw type. Task::new

can be assigned Callable<Task>

because it is something that takes no parameters and returns a task.

+4


source


To implement the interface, Callable<V>

you must implement a method with a signature V call()

.

Hence, you can implement this interface with method references of any methods that accept nothing and return some reference type that includes constructor method references such as Task::new

.



In fact, any class that has a parameterless constructor can be used like this:

Callable<SomeClass> callable = SomeClass::new;

      

+2


source







All Articles