invokeAll()不愿意接受Collection <Callable >

我不明白为什么这段代码不能编译

ExecutorService executor = new ScheduledThreadPoolExecutor(threads); class DocFeeder implements Callable {....} ... List list = new LinkedList(); list.add(new DocFeeder(1)); ... executor.invokeAll(list); 

错误消息是:

 The method invokeAll(Collection<Callable>) in the type ExecutorService is not applicable for the arguments (List) 

listDocFeederCollection ,它实现了Callable – 发生了什么?!

只是为了扩大saua的答案……

在Java 5中,该方法被声明为:

 invokeAll(Collection> tasks) 

在Java 6中,该方法声明为:

 invokeAll(Collection> tasks) 

通配符的区别非常重要 – 因为List 一个Collection> Collection>但它不是 Collection> 。 考虑一下这种方法会发生什么:

 public void addSomething(Collection> collection) { collection.add(new SomeCallable()); } 

这是合法的 – 但如果您可以使用List调用addSomething ,那将是非常糟糕的,因为它会尝试将非DocFeeder添加到列表中。

因此,如果您遇到Java 5,则需要从List创建List>

该代码与Java 6编译完美,但无法使用Java 5编译

  Foo.java:9:找不到符号
 symbol:方法invokeAll(java.util.List)
 location:interface java.util.concurrent.ExecutorService
 executor.invokeAll(列表);
         ^
 1错误 

但是更改list如下:

 Collection> list = new LinkedList>(); 

使其适用于Java 5和Java 6。

感谢详细解答,但它仍然让我感到困惑–Callable是一个接口,所以实际上,Jon的答案中的“addSomething”函数应该没问题(不仅合法,而且合理) – 因为,这就是接口的全部要点 – 只要您遵守一些初步协议,我就不关心您要添加到列表中的对象。 imo,你提出的问题应该在不同的范围内解决。

除此之外,事实仍然是代码没有编译 – 它应该……

 Collection> list = new LinkedList>();