泛型将子类添加到数组中

时间:2016-04-25 13:39:07

标签: java generics inheritance

我有一个 B 类,它扩展了 A A 存储 AItem 列表, B 列出 BItem

列表

在' A'我有 ArrayList ,它使用[?扩展AItem ]。

我认为这意味着我可以将此ArrayList用于任何扩展AItem的类型的对象。

所以在我的B类中,我有一个方法add(..),它为项添加了一个BItem。

我认为这样可行,因为itemsList可以保存从AItem扩展的任何对象的列表。

import java.util.ArrayList;

class A {
    public ArrayList<? extends AItem> items;
}

public class B extends A{

    public void add(BItem i) {

        this.items.add(i); //compile error here
    } 
}

//items :
class AItem {}
class BItem extends AItem{}

我怎样才能让它发挥作用?

我的编译错误如下所示:

  

该方法在类型中添加(捕获#2-of?extends AItem)   ArrayList不适用于   参数(BItem)

3 个答案:

答案 0 :(得分:6)

您可能不需要在这里使用泛型。在类AItem中使用A类型的列表应该没问题(我还会声明类型List而不是ArrayList以获得最佳做法):

class A {
    public List<AItem> items;
}

class B extends A {

    public void add(BItem i) {

        this.items.add(i);
    } 
}

? extends AItem的问题在于编译器无法保证元素的实际类型为AItemBItem。它可能是另一个子类CItem,在这种情况下,类型安全性会被破坏。

另一种使用泛型设计类层次结构的方法,您可以在其中设置父类中的type参数并将其设置为扩展中的相应子类(BItem)班B

class A<T extends AItem> {
    public ArrayList<T> items;
}

class B extends A<BItem>{

    public void add(BItem i) {

        this.items.add(i);
    } 
}

答案 1 :(得分:2)

尝试将extends替换为super

import java.util.ArrayList;

class A {
    public ArrayList<? super AItem> items;
}

public class B extends A{

    public void add(BItem i) {

        this.items.add(i); //compile error here
    } 
}

//items :
class AItem {}
class BItem extends AItem{}

您可以找到有关此行为背后原因的更多详细信息,here

答案 2 :(得分:1)

你可以使用

public ArrayList<? super AItem> items; 

您可以立即添加到列表中

但你将无法做到

public class B extends A{
 .....

   public BItem getOne(int idx) {
     return this.items.get(idx);

   }
}

jvm不知道列表中的实际内容。

你可以生成A类

class  A<T> {
    public ArrayList<T> items;
}

然后将您的B类定义为

public class B extends A<BItem>{

    public void add(BItem i) {

        this.items.add(i); 
    } 
}