JavaFX任务的Lambda表达式

7
编译器给我报错:“目标类型必须是一个接口”针对这段代码:
Task<Iterable<Showing>> task = () -> sDAO.listFiltered();

listFiltered() 的返回类型为 Iterable<Showing>。 我如何使用带有 lambda 的 Task 接口?

1个回答

13

Task 是一个抽象类而不是接口,因此不能直接使用 lambda 表达式创建它。

通常情况下,您可以使用内部类来继承 Task

Task<Iterable<Showing>> task = new Task<Iterable<Showing>>() {
    @Override
    public Iterable<Showing> call throws Exception {
        return sDAO.listFiltered();
    }
});

如果您想使用lambda表达式创建Task的功能,您可以创建一个可重用的实用方法来为您完成此操作。由于您需要在Task中实现的抽象方法call具有与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());

在OpenJDK邮件列表中,有一个关于为什么不允许使用lambda表达式创建具有单个抽象方法的抽象类(有效地)子类的解释


非常感谢您提供这个有用的答案! - Domien
现在唯一的问题是我不能使用返回void类型的方法。它会显示“无法将void转换为Void”。 - Domien
无论是 Task 中的 call 方法还是 Callable 中的 call 方法都不能是 void。相反,声明它们返回一个 Void 并返回 null(这是 Void 引用类型的唯一合法值)。 - James_D

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接