所以我正在使用ExecutorService并希望生成Callables以便我可以使用invokeAll执行它们
Callables有不同的返回类型。这让我觉得我可以使用外卡完成
Set<Callable<?>> executedCallables = new HashSet<Callable<?>>();
executedCallables.add(serviceHelper.getOwnerDetails()); --> returns Callable<OwnerDetails>
executedCallables.add(iqmServiceHelper.getUserDetails()); --> returns Callable<UserDetails>
以类似的方式我为invokeAll添加了语句
List<Future<? extends Object>> futures = executorService.invokeAll(executedCallables);
ad这给了我编译器错误The method invokeAll(Collection<? extends Callable<T>>) in the type ExecutorService is not applicable for the arguments (Set<Callable<?>>)
,我没有得到如何解决。
有人可以指出使用中的错误并正确使用。
编译错误就是来自JDK 6.而且我认为在更高版本的JDK中会有所不同
上也有类似的StackOverflow线程答案 0 :(得分:2)
问题是invokeAll的签名有点过于严格。它应该是Collection<? extends Callable<? extends T>>
,因为T是这里的生产者(记得来自Effective Java:PECS - Producer Extends Consumer Super)。
但是我们当然不能在这里改变JDK方法,所以我们必须忍受它。解决方案是传入Set<Callable<Object>
&gt;并使用不安全的强制转换(这是安全的,因为您只从Callable中提取T类型的值)或使用方法引用:
Set<Callable<Object>> callables = new HashSet<>();
callables.add((Callable) serviceHelper.getOwnerDetails()); // method one
callables.add(iqmServiceHelper.getUserDetails()::call); // method two
最终陈述将如下所示
try {
List<Future<Object>> futures = executorService.invokeAll(executedCallables);
} catch (InterruptedException e) {
e.printStackTrace();
}