为何提交JavaFX Task至Executor会返回Future<*>?如何获取正确类型?
解决JavaFX Task提交后获取正确类型Future的问题
首先纠正你代码里的笔误:你提到Def是Callable类,所以它的定义应该是class Def : Callable<Foo>() { ... },而非继承自Task。
问题原因
JavaFX的Task<T>继承自FutureTask<T>,而FutureTask<T>实现了Runnable接口。当你调用ExecutorService.submit(Task)时,会匹配到submit(Runnable)的重载方法,该方法返回Future<?>,而非泛型匹配的Future<T>。
两种解决方法
方法1:直接利用Task本身的Future特性
Task<T>本身就是Future<T>的实现类(因为继承自FutureTask<T>),所以不需要通过submit的返回值获取Future,直接调用executor.execute(task)后,用Task实例本身作为Future<T>即可:
val abc = Abc() val executor = Executors.newSingleThreadExecutor() executor.execute(abc) val future: Future<Foo> = abc // 类型完全匹配
方法2:将Task包装为Callable提交
显式把Task包装成Callable<T>,这样会匹配ExecutorService.submit(Callable<T>)的重载,返回正确的Future<Foo>:
val abc = Abc() val executor = Executors.newSingleThreadExecutor() val future: Future<Foo> = executor.submit(Callable { abc.call() })
更适合JavaFX的实现方式
如果是JavaFX应用场景,更推荐使用Task自带的回调方法处理结果,而非手动操作Future。这些回调会自动在JavaFX应用线程执行,避免UI更新的线程安全问题:
val abc = Abc() // 任务成功完成时的回调(在FX线程执行) abc.setOnSucceeded { event -> val result: Foo = event.source.value // 在这里安全更新UI组件 } // 任务失败时的回调(在FX线程执行) abc.setOnFailed { event -> val exception = event.source.exception // 处理异常逻辑 } // 提交任务到后台线程 Executors.newSingleThreadExecutor().execute(abc)
内容的提问来源于stack exchange,提问作者vbyzjnlehi
相关产品推荐
相关产品推荐

