The compiler gives me this error \"Target Type of lambda expression must be an interface\" for this code:
Task> task = () ->
Task
is an abstract class, not an interface, and so it cannot be directly created with a lambda expression.
You would typically just use an inner class to subclass Task
:
Task<Iterable<Showing>> task = new Task<Iterable<Showing>>() {
@Override
public Iterable<Showing> call throws Exception {
return sDAO.listFiltered();
}
});
If you want the functionality of creating a Task
with a lambda expression, you could create a reusable utility method to do that for you. Since the abstract method call
that you need to implement in Task
has the same signature as the interface method in Callable
, you could do the following:
public class Tasks {
public static <T> Task<T> create(Callable<T> callable) {
return new Task<T>() {
@Override
public T call() throws Exception {
return callable.call();
}
};
}
}
Since Callable
is a FunctionalInterface
(i.e. an interface with a single abstract method), it can be created with a lambda expression, so you could do
Task<Iterable<Showing>> task = Tasks.create(() -> sDAO.listFiltered());
There is an explanation of why lambdas are not allowed to be used to create (effectively) subclasses of abstract classes with a single abstract method on the OpenJDK mailing list.