我刚刚阅读了Java中的Wild Cards,我正在研究一个案例,其中有两个类,ParentClass和SubClass继承自它。 (ParentClass,SubClass扩展ParentClass)
现在我写下这些行。
List<? super ParentClass> list1 = new ArrayList<ParentClass>();
list1.add(new SubClass());
我无法理解为什么这会编译并运行。第2行不应该导致编译错误,因为我试图将ParentClass的子节点添加到应该只包含ParentClass父亲的列表中吗?
谢谢!
答案 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
。因此,无论方法list
中x
的类型如何,对add
的调用都会保留类型安全。
答案 1 :(得分:1)
继承关系表示为&#34;是&#34;:SubClass
是ParentClass
,ParentClass
是其超类的实例,等等。编码时,您始终可以在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:抱歉我的英语不好。