0

我以为我已经用super. 但我一定是完全错误的:

用这个简单的例子:

class Animal{}
class Dog extends Animal{}

这段代码运行良好,因为我们传入了一个 Dog 的超类:

static void addThis(ArrayList<? super Dog> a) {
    a.add(new Dog());
}
...
ArrayList<Animal> dogs=new ArrayList();
addThis(dogs);

但是,我不明白的是我认为这是同一件事:

ArrayList<? super Dog> dogs2=new ArrayList();
dogs2.add(new Animal());

但它无法编译。两者有什么区别?


顺便说一句,我想偷偷问另一个问题。有没有区别

// This...
ArrayList<Animal> dogs=new ArrayList();
// ... and this?
ArrayList<Animal> dogs=new ArrayList<Animal>();

鉴于类型擦除在编译时将其删除,我认为这与编译器检查引用类型是一样的。它是否正确?

4

3 回答 3

4

这根本不是一回事。在一种情况下,您要添加一个Dog,在另一种情况下,您要添加一个Animal.

在这两种情况下,您只知道Dogs 是允许的,因此第二种情况失败。

要回答您的第二个问题,这有区别的,您应该始终使用第二个版本。(然而,在 Java 7+ 中,您可以通过编写 . 请求编译器为您推断泛型类型new ArrayList<>()。)

于 2013-02-12T23:15:33.293 回答
0

Dog 是 Animal,因此您可以将 to 施法ArrayList<? extends Dog>ArrayList<Animal>但您不能反其道而行,因为 Animal 不一定是 Dog。

例如:

public class Cat extends Animal{}

因为这没有意义:

ArrayList<Dog> dogList = new ArrayList<Dog>();
dogList.add(new Cat());

您不能将动物添加到“狗”列表中,因为该动物可以是猫。

这是 Java 类型安全的一个示例。

于 2013-02-12T23:16:45.710 回答
0

简而言之,List<? super Dog>是具有super(父)作为Dog的对象列表,而不是属于的对象super列表Dog

于 2013-02-12T23:27:24.457 回答