【问题标题】:Java inheritance structure problemJava继承结构问题
【发布时间】:2011-06-05 14:49:10
【问题描述】:

我刚刚实现了一些类:

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&lt;MyReturnJob&gt; list = new LinkedList&lt;MyReturnJob&gt;();

JobExecuter.execute(list); 也抛出同样的错误

感谢您的帮助。

最好的问候, 直到

【问题讨论】:

    标签: java inheritance polymorphism


    【解决方案1】:

    这里有什么问题??

    问题不是从LinkedListList 的变化,而是包含类型的变化。 Java 泛型不是协变的,这意味着你甚至不能这样做:

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

    详情...

    有关更多信息,请阅读"Java theory and practice: Generics gotchas" 文章。这里是它的相关部分:

    事实证明它不起作用是有充分理由的(...):它会破坏泛型应该提供的类型安全。想象一下,您可以将List&lt;Integer&gt; 分配给List&lt;Number&gt;。然后下面的代码将允许您将不是Integer 的内容放入List&lt;Integer&gt;

    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> {
    [...]
    }
    

    【讨论】:

    • @奥利查尔斯沃思。好的,非常感谢。如果我将我的 Listdef 更改为 LinkedList&lt;MyReturnJob&gt; list = new LinkedList&lt;MyReturnJob&gt;(); 并将 JobExecuter 更改为 public static void execute(List&lt;? extends Job&gt; jobList){[...] 一切都会正常工作吗?
    • @Till:GetBetAmountJob 是什么?
    • @Oli Charlesworth 对不起。错字,现在是 MyReturnJob
    【解决方案2】:

    问题是您不能为集合分配不同的参数化类型,即使这些参数化类型通常是可分配的。

    您可能正在寻找类似的内容:

    List<Job> list = new LinkedList<Job>();
    JobExecuter.execute( list );
    
    public static void execute( List<? extends Job> jobList )
    { ... }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-20
      • 2014-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-14
      • 2011-04-22
      相关资源
      最近更新 更多