编译器给我这个错误"目标lambda表达式的类型必须是一个接口"对于此代码:
Task<Iterable<Showing>> task = () -> sDAO.listFiltered();
listFiltered()
的返回类型为Iterable<Showing>
。
如何使用lambda的Task
接口?
答案 0 :(得分:11)
Task
是一个抽象类,不是接口,因此无法使用lambda表达式直接创建。
您通常只使用内部类来继承Task
:
Task<Iterable<Showing>> task = new Task<Iterable<Showing>>() {
@Override
public Iterable<Showing> call throws Exception {
return sDAO.listFiltered();
}
});
如果您想要使用lambda表达式创建Task
的功能,您可以创建一个可重用的实用程序方法来为您执行此操作。由于您需要在call
中实现的抽象方法Task
与Callable
中的接口方法具有相同的签名,因此您可以执行以下操作:
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();
}
};
}
}
由于Callable
是FunctionalInterface
(即具有单个抽象方法的接口),因此可以使用lambda表达式创建它,所以你可以这样做
Task<Iterable<Showing>> task = Tasks.create(() -> sDAO.listFiltered());
有一个explanation为什么不允许使用lambdas在OpenJDK邮件列表上用一个抽象方法创建(有效)抽象类的子类。