关于Java中的Wild Cards的简单说明

时间:2014-09-05 19:49:54

标签: java generics bounded-wildcard

我刚刚阅读了Java中的Wild Cards,我正在研究一个案例,其中有两个类,ParentClass和SubClass继承自它。 (ParentClass,SubClass扩展ParentClass)

现在我写下这些行。

List<? super ParentClass> list1 = new ArrayList<ParentClass>();
list1.add(new SubClass());

我无法理解为什么这会编译并运行。第2行不应该导致编译错误,因为我试图将ParentClass的子节点添加到应该只包含ParentClass父亲的列表中吗?

谢谢!

4 个答案:

答案 0 :(得分:4)

类型List<? super ParentClass>表示&#34;最多为ParentClass&#34;的某种未知类型的列表。如果您有一个接受此类型参数的方法,您可以将其传递给List<ParentClass>List<GrandparentClass>,...,List<Object> ......

void x(List<? super ParentClass> list) {
    list.add(new SubClass());
}

这些类型的任何列表都会允许使用add类型的参数调用SubClass。因此,无论方法listx的类型如何,对add的调用都会保留类型安全。

答案 1 :(得分:1)

继承关系表示为&#34;是&#34;:SubClassParentClassParentClass是其超类的实例,等等。编码时,您始终可以在SubClass或其任何祖先的任何地方设置ParentClass

SubClass subClass = new SubClass();
ParentClass aParent = subClass;

答案 2 :(得分:0)

根据Java多态性功能 您的子类对象可以分配给父类的引用类型。 这里它将子类分配给ParentClass类型的引用。

这就是它工作的原因

您好,

[这](What is PECS (Producer Extends Consumer Super)?)应该真正帮助你理解。有一条叫做PECS的规则。制片人扩展和消费者超级。这个规则应该包含在Java通配符的通配符中,因为没有它,对有界通配符的理解对我来说似乎不完整。

基本上暗示,如果你只想从List中读取(不写入它),那么使用

 List<? extends ParentClass> 

它表示您将获得ParentClass或ParentClass子类型的对象。此外,暗示List处于只读模式。

如果你想放置&#39;进入未读取的列表,然后将列表声明为

 List<? Super ParentClass> 

您可以添加ParentClass或其类型的类型。但是没有别的东西可以投入。

另外,编写了以下代码和

1   List<? super ChildClass > list1 = new ArrayList<ChildClass>();
2       list1.add(new GrandChildAbstract());
3      list1.add(new ChildClass());
4     list1.add(new Abstractclass());
5      
6       ChildClass ch=  list1.get(0);
7       Abstractclass ch = list1.get(0);
8       
9       List<? extends ChildClass> list2 = new ArrayList<ChildClass>();
10       list2.add(new GrandChildAbstract());
11       list2.add(new ChildClass());
12      list2.add(new Abstractclass());

Eclipse编译时出错了#4,6,7和10,11,12行。 这清楚地表明,必须在只读和只写上下文的上下文中理解超绑定通配符。

答案 3 :(得分:0)

好吧,你似乎对这些条款感到困惑。

当你说

List<? super ParentClass> list1;

你说,list1将接受列表类型为ParentClass或以上的所有列表。

此代码不起作用,因为SubClass不是ParentClass的超类。

List<? super ParentClass> list1 = new ArrayList<SubClass>();

写作时

List<? super ParentClass> list1 = new ArrayList<ParentClass>();

等于

List<ParentClass> list1 = new ArrayList<ParentClass>();

一旦SubClass是ParentClass的子类型:

list1.add(new SubClass());

正常运行。

ps:抱歉我的英语不好。