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 в ответе Джона должна быть в порядке (не только законной, но и разумной) - потому что, в этом-то и весь смысл интерфейсов - Пока вы выполняете какое-то первоначальное соглашение, мне все равно, какой объект вы добавите в список. ИМХО, проблема, которую вы представили, должна решаться в другом контексте.
Кроме того, факт остается фактом, что код не компилировался - и он должен был...