-1

我是 Java 泛型的新手,我目前正在尝试使用泛型编码......最终目标是将旧的非泛型遗留代码转换为泛型......

我已经用 IS-A 定义了两个类,即一个是另一个的子类。

public class Parent {
    private String name;
    public Parent(String name) {
        super();
        this.name = name;
    }
}

public class Child extends Parent{
    private String address;
    public Child(String name, String address) {
        super(name);
        this.address = address;
    }
}

现在,我正在尝试使用有界通配符创建一个列表。并得到编译器错误。

List<? extends Parent> myList = new ArrayList<Child>(); 
myList.add(new Parent("name")); // compiler-error
myList.add(new Child("name", "address")); // compiler-error
myList.add(new Child("name", "address")); // compiler-error

有点糊涂。请帮我看看这有什么问题?

4

2 回答 2

6

那是因为你创造了ArrayList<Child>

为了达到同样的效果(即创建一个List可以容纳 的所有子类Parent),您可以简单地将其声明为List<Parent> myList = new ArrayList<Parent>();

List<Parent> myList = new ArrayList<Parent>(); --> new ArrayList should have generic type Parent
myList.add(new Parent("name")); // will work
myList.add(new Child("name", "address")); // will work
myList.add(new Child("name", "address")); // will work

编辑:

为了回答您的其他困惑,在上限通配符类型上书写是非法的,这里有一个解释为什么会这样的线程。

于 2013-06-30T05:56:46.967 回答
0

这就是编译错误的原因:

List<?> myList2 = new ArrayList<Child>(); 
myList2.add(new Child("name", "address")); // compiler-error

List<? extends Parent> myList2 = new ArrayList<Child>(); 
myList1.add(new Child("name", "address")); // compiler-error

由于我们不知道myList2/myList1的元素类型代表什么,我们无法向其中添加对象。add() 方法接受类型 E 的参数,即集合的元素类型。当实际类型参数为 ? 时,它代表某种未知类型。我们传递给 add 的任何参数都必须是这种未知类型的子类型。因为我们不知道那是什么类型,所以我们不能传入任何东西。唯一的例外是 null,它是每个类型的成员。

另一方面,给定一个 List < ? >/列表< ? extends Parent>,我们只能调用 get() 并使用结果。

于 2013-06-30T13:02:57.987 回答