InvokeAll() не желает принимать коллекцию <Callable <T>>

Я не понимаю, почему этот код не будет компилироваться

ExecutorService executor = new ScheduledThreadPoolExecutor(threads);

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

Ошибка msg:

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

list является Collection of DocFeeder, который реализует Callable<Boolean> - Что происходит?!

Ответ 1

Просто, чтобы расшириться на 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>.

Ответ 2

Этот код отлично компилируется с 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.

Ответ 3

Спасибо за подробный ответ, но он все еще меня задевает - Callable - это интерфейс, так что на самом деле функция "addSomething" в ответе Джона должна быть в порядке (не только законной, но и разумной), потому что, точка интерфейсов. Пока вы выполняете какое-то первоначальное соглашение, мне все равно, какой объект вы бы добавили в список. imo, проблема, которую вы представили, должна быть рассмотрена в другом объеме.

Кроме того, факт остается фактом: код не компилировался - и он должен иметь...

Ответ 4

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