如何使用泛型

时间:2016-12-01 23:21:58

标签: java generics collections

所以我正在使用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中会有所不同

PS: - 此Collection of Callable and Generics

上也有类似的StackOverflow线程

1 个答案:

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