我刚刚实现了一些类:
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转换为List
我不知道为什么,因为MyReturnJob
继承了Job
。
如果我将列表的定义更改为LinkedList<MyReturnJob> list = new LinkedList<MyReturnJob>();
JobExecuter.execute(list);
感谢您的帮助。
祝你好运, 直到
答案 0 :(得分:6)
问题不在于从LinkedList
到List
的更改,而是包含类型的更改。 Java泛型不是协变,这意味着你甚至无法做到:
LinkedList<Job> = new LinkedList<MyReturnJob>();
有关详情,请参阅"Java theory and practice: 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 :(得分:1)
问题在于您无法为不同参数化类型的集合分配,即使这些参数化类型通常是可分配的。
您可能正在寻找的是:
List<Job> list = new LinkedList<Job>();
JobExecuter.execute( list );
public static void execute( List<? extends Job> jobList )
{ ... }