【发布时间】:2013-11-23 17:53:21
【问题描述】:
Java。集合中的通配符
我在理解集合中的通配符时遇到了很多麻烦,即使在阅读了 Stack Overflow 和各种教程网站上的类似帖子之后也是如此。我在下面做了一个非常简单的例子。你能解释一下我将如何在Collection< myClass >、Collection< ? Extends MyClass > 和Collection< ? Super MyClass > 之间进行选择吗?
package z5;
import java.util.ArrayList;
public class Z5 {
public static class Animal{
}
public static class Mammal extends Animal{
}
public static class Reptile extends Animal{
}
public static class Lion extends Mammal{
}
public static class Tiger extends Mammal{
}
public static class Snake extends Reptile{
}
public static void main(String[] args) {
ArrayList<Mammal> catHouse1 = new ArrayList<Mammal>();
catHouse1.add(new Lion());
catHouse1.add(new Tiger());
catHouse1.add(new Mammal());
catHouse1.add(new Animal()); //ERROR
ArrayList<? super Mammal> catHouse2 = new ArrayList<Mammal>();
catHouse2.add(new Lion());
catHouse2.add(new Tiger());
catHouse2.add(new Mammal());
catHouse2.add(new Animal()); //ERROR
ArrayList<? extends Mammal> catHouse3 = new ArrayList<Mammal>();
catHouse3.add(new Lion()); //ERROR
catHouse3.add(new Tiger()); //ERROR
catHouse3.add(new Mammal()); //ERROR
catHouse3.add(new Animal()); //ERROR
ArrayList<Mammal> zooMammals = new ArrayList<Mammal>();
zooMammals.addAll(catHouse1);
zooMammals.addAll(catHouse2); //ERROR
zooMammals.addAll(catHouse3);
ArrayList<Animal> zooAnimals = new ArrayList<Animal>();
zooAnimals.addAll(catHouse1);
zooAnimals.addAll(catHouse2); //ERROR
zooAnimals.addAll(catHouse3);
}
}
在上面的示例中,我创建了类的层次结构。动物是哺乳动物和爬行动物的超类,哺乳动物是狮子和老虎的超类。
我为动物园里的三个猫屋制作了 ArrayList。第一个是简单的 ArrayList。我可以添加任何类型的哺乳动物或其子类的对象。
第二个是 ArrayList。我还可以添加任何类型的哺乳动物或其子类的对象。
第三个是 ArrayList。我不能添加任何东西。
最后,我将我的三个猫屋添加到动物园收藏中。 Animal 和 Mammal 是这里的主要超类,无论接收者 ArrayList 持有哪种类型,行为都是相同的。 ArrayList 和 ArrayList 可以添加到动物园。 ArrayList 不能。
这是我的问题:
1) 如果我想创建一个包含某个超类的所有子类的数组,为什么需要通配符?我不能只声明所有 ArrayList 并获得我需要的功能吗?
2) 我了解“”接受超类及其所有子类。因此," 接受 Mammals、Lions 和 Tigers。这听起来完全像 ""。有什么区别?
3) 我读到“”接受任何作为 className 超类的类。这听起来不对。在上面的例子中,Lions 不是 Mammals 的超类,但是 " super Mammal >" 接受 Lions。动物是哺乳动物的超类,但“”不接受它。我认为我的信息有误。
4) 如果 "" 是只读的,我如何开始填充它?拥有一个只能读取的空列表有什么意义?
5) 为什么addAll方法对“”不起作用?
我知道这些是基本问题,而且我知道之前已经回答过这些问题。我试图给出一个尽可能简单的代码示例,并希望能给我一个尽可能清晰的答案。提前感谢您提供的任何建议。
【问题讨论】:
标签: java collections wildcard