2016-12-01 30 views
3

所以我用的ExecutorService,想要产生可调用,这样我可以使用的invokeAll如何得到正确的语句中使用泛型

的可调用对象有不同的返回类型执行。这让我觉得我可以以类似的方式,使用通配符

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

广告这给了我编译器错误The method invokeAll(Collection<? extends Callable<T>>) in the type ExecutorService is not applicable for the arguments (Set<Callable<?>>)这我没有得到如何解决得到完成。

有人可以指出使用中的错误和正确的用法。

刚抬起头编译器错误是JDK 6,我不认为将是更高的版本不同的JDK

PS: - 有一个类似的StackOverflow线程以及这个Collection of Callable and Generics

回答

2

问题是invokeAll的签名有点过于严格。它应该是Collection<? extends Callable<? extends T>>,因为T在这里是一个生产者(记得从Effective Java:PECS - Producer Extends Consumer Super)。 但是,我们当然不能在这里更改JDK方法,所以我们必须忍受它。溶液处于Set<Callable<Object>传递>和或者使用一个不安全的铸造(其是安全的,因为你只提取类型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(); 
} 
+0

感谢您的答复。上述声明构造良好我还没有得到如何纠正最终陈述列表<未来<? extends Object >> futures = executorService.invokeAll(executedCallables); – Acewin

+1

你不会拿出一个'List >',你会得到'List >'。 这里没有办法使'T'成为通配符。 – diesieben07

+0

谢谢,我会建议你把这点加到你的解决方案中 – Acewin