Проблема структуры наследования Java - PullRequest
2 голосов
/ 05 июня 2011

Я только что реализовал несколько классов:

public abstract class Job<T extends ViewerUnion>{
[...]
}

public abstract class ReturnValueJob<T, S extends ViewerUnion> extends Job<S> {
[...]
}

public class MyReturnJob extends ReturnValueJob<Foo, Baa> {
[...]
}

public class JobExecuter {
public static void execute(List<Job> jobList){
for(Job actJob: jobList){
    actJob.startJob();
}
for(Job actJob: jobList){
    actJob.awaitTimeoutOrFinish();
}
}
}

Теперь я хочу выполнить этот код:

List<Job> list = new LinkedList<MyReturnJob>();
JobExecuter.execute(list);

Но Java выдает ошибку при компиляции:

Несоответствие типов: невозможно преобразовать LinkedList в список

Я не знаю почему, потому что MyReturnJob наследует Job.Если я изменю определение списка на LinkedList<MyReturnJob> list = new LinkedList<MyReturnJob>();

Та же ошибка выдается JobExecuter.execute(list);

Спасибо за вашу помощь.

С уважением, До

Ответы [ 2 ]

6 голосов
/ 05 июня 2011

Что здесь не так ??

Проблема не в изменении с LinkedList на List, а в изменении типа .Обобщения Java не являются ковариантными , что означает, что вы даже не можете сделать:

LinkedList<Job> = new LinkedList<MyReturnJob>();

Подробнее ...

Для получения дополнительной информации прочитайте "Теорию Javaи практика: Generics gotchas " статья.Вот его релевантная часть:

Оказывается, есть веская причина, по которой он не работает (...): Это нарушило бы непатентованные типы безопасности, которые должны были обеспечить .Представьте, что вы можете назначить List<Integer> на List<Number>.Тогда следующий код позволит вам поместить что-то, что не было Integer в List<Integer>:

List<Integer> li = new ArrayList<Integer>();
List<Number> ln = li; // illegal
ln.add(new Float(3.1415));

... применено обратно к контексту

Код примера статьи можно перевести в контекст этого вопроса следующим образом:

List<MyReturnJob> li = new LinkedList<MyReturnJob>();
List<Job> ln = li; // illegal
ln.add(new FooJob());

, где FooJob объявлено как:

public abstract FooJob extends Job<ViewerUnion> {
[...]
}
1 голос
/ 05 июня 2011

Проблема в том, что вы не можете назначать коллекции с другими параметризованными типами, даже если эти параметризованные типы обычно назначаются.

То, что вы, вероятно, ищете, выглядит примерно так:

List<Job> list = new LinkedList<Job>();
JobExecuter.execute( list );

public static void execute( List<? extends Job> jobList )
{ ... }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...