invokeAll () не хочет принимать коллекцию <Callable <T>> - PullRequest
8 голосов
/ 16 декабря 2008

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

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 ]

18 голосов
/ 16 декабря 2008

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

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

invokeAll(Collection<Callable<T>> tasks) 

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

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

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

7 голосов
/ 16 декабря 2008

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

0 голосов
/ 16 апреля 2009
Collection<Callable<Boolean>> list = new LinkedList<Callable<Boolean>>();
0 голосов
/ 16 декабря 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...