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