Just found a strange and interesting Lambda behavior.
Let's have the following class:
private class Task implements Runnable {
@Override
public void run() {
// something to process
}
}
The following statement is compiling and running:
Callable task = Task::new;
Could somebody explain why this is possible ?
EDIT:
Based on answers below, check the following statements:
1.
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(Task::new);
2.
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(new Task());
On the first glance, seems the same, but actually does a totally different thing.
What happens here is exactly the above situation.
The reason is that ExecutorService has two methods:
submit(Runnable);
submit(Callable);
So, using the code from 1. the executor will process the following on it's internal thread:
new Task()
The version from 2. will actually call the submit(Runnable) method and the code from Task.run will be executed.
Conclusion: just be careful with Lambdas :)
The Callable is not initialized with a Runnable instance, it is initialized with a method reference to the Task constructor that will produce a Runnable when executed.
In other words, if you execute that Callable, it will return a new Task object that has not yet been run. That Task implements Runnable is actually completely irrelevant here.
This would be clearer if you didn't use the raw type. Task::new can be assigned to Callable<Task> because it is something that takes no parameters and returns a Task.
To implement the Callable<V> interface one must implement a method with the signature V call().
Therefore, you can implement this interface with method references of any methods that take nothing and return some reference type, which includes constructor method references such as Task::new.
In fact, any class having a parameter-less constructor can be used this way:
Callable<SomeClass> callable = SomeClass::new;
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