【问题标题】:Lambda for JavaFX Task用于 JavaFX 任务的 Lambda
【发布时间】:2018-05-02 00:23:57
【问题描述】:

编译器给我这个错误“lambda表达式的目标类型必须是接口”:

Task<Iterable<Showing>> task = () -> sDAO.listFiltered();

listFiltered() 的返回类型是Iterable&lt;Showing&gt;。 如何将Task 接口与 lambda 一起使用?

【问题讨论】:

    标签: java javafx


    【解决方案1】:

    Task是抽象类,不是接口,所以不能直接用lambda表达式创建。

    你通常只使用一个内部类来继承Task

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

    如果您想要使用 lambda 表达式创建 Task 的功能,您可以创建一个可重用的实用程序方法来为您执行此操作。由于您需要在Task 中实现的抽象方法callCallable 中的接口方法具有相同的签名,因此您可以执行以下操作:

    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();
                }
            };
        }
    }
    

    由于CallableFunctionalInterface(即具有单个抽象方法的接口),因此可以使用 lambda 表达式创建它,因此您可以这样做

    Task<Iterable<Showing>> task = Tasks.create(() -> sDAO.listFiltered());
    

    在 OpenJDK 邮件列表中,有一个 explanation 说明为什么不允许使用 lambda 来创建(有效地)具有单个抽象方法的抽象类的子类。

    【讨论】:

    • 非常感谢您提供这个有用的答案!
    • 现在唯一的问题是我不能用返回 void 类型的方法来做到这一点。它说“无效不能转换为无效”
    • TaskCallable 中的call 方法都不能是void。相反,声明它们返回 Void 并返回 nullVoid 引用类型的唯一合法值)。
    猜你喜欢
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多