invokeAll()不愿意接受Collection <callable <t>&gt; </callable <t>

时间:2008-12-16 08:33:17

标签: java executorservice callable

我无法理解为什么这段代码无法编译

ExecutorService executor = new ScheduledThreadPoolExecutor(threads);

class DocFeeder implements Callable<Boolean> {....} 
... 
List<DocFeeder> list = new LinkedList<DocFeeder>();
list.add(new DocFeeder(1));
...
executor.invokeAll(list);

错误消息是:

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

listCollection的{​​{1}},它实现DocFeeder - 发生了什么?!

4 个答案:

答案 0 :(得分:18)

稍微扩展一下saua的答案......

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

invokeAll(Collection<Callable<T>> tasks) 

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

invokeAll(Collection<? extends Callable<T>> tasks) 

通配符差异非常重要 - 因为List<DocFeeder> Collection<? extends Callable<T>>但是不是 a Collection<Callable<T>>。考虑一下这种方法会发生什么:

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

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

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

答案 1 :(得分:7)

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

Foo.java:9: cannot find symbol
symbol  : method invokeAll(java.util.List)
location: interface java.util.concurrent.ExecutorService
executor.invokeAll(list);
        ^
1 error

无论如何更改list

Collection<Callable<Boolean>> list = new LinkedList<Callable<Boolean>>();

使其适用于Java 5和Java 6.

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

Collection<Callable<Boolean>> list = new LinkedList<Callable<Boolean>>();