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

Сообщение об ошибке:

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

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

4 ответа

Решение

Просто чтобы немного расширить ответ Сауа...

В Java 5 метод был объявлен как:

invokeAll(Collection<Callable<T>> tasks) 

В Java 6 метод объявлен как:

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

Разница с подстановочными знаками очень важна - потому что List<DocFeeder> это Collection<? extends Callable<T>> но это не 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>,

Этот код прекрасно компилируется с Java 6, но не компилируется с Java 5, давая

Foo.java:9: не могу найти символ
символ: метод invokeAll(java.util.List)
расположение: интерфейс java.util.concurrent.ExecutorService
executor.invokeAll(список);
        ^
1 ошибка

Однако изменение list как это:

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

Заставляет его работать как на Java 5, так и на Java 6.

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

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

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

Другие вопросы по тегам