Reputation: 667
I just read about Wild Cards in Java, and I'm looking at a case in which I have 2 classes, ParentClass and SubClass which inherits from it. (ParentClass, SubClass extends ParentClass)
Now I write these lines.
List<? super ParentClass> list1 = new ArrayList<ParentClass>();
list1.add(new SubClass());
I can't understand why this compiles and runs. Shouldn't line 2 cause a compilation error, since I'm trying to add a child of ParentClass to a list that is supposed to hold only fathers of ParentClass?
Thank you!
Upvotes: 0
Views: 101
Reputation: 3917
Well, it seems you are confusing the terms.
When you say
List<? super ParentClass> list1;
you are saying, list1 will accept all list that the type of the list is ParentClass or above.
this code doesn't work, because SubClass is not a superclass of ParentClass.
List<? super ParentClass> list1 = new ArrayList<SubClass>();
When you write
List<? super ParentClass> list1 = new ArrayList<ParentClass>();
is equals to
List<ParentClass> list1 = new ArrayList<ParentClass>();
and once SubClass is subtype of ParentClass:
list1.add(new SubClass());
runs normally.
ps: sorry for my bad english.
Upvotes: 0
Reputation: 2752
According to Java Polymorphism feature your subclass object can be assigned to a reference type of Parent class. Here it is assigning subclass to a reference of type ParentClass.
That is why its working
Hi,
[This] (What is PECS (Producer Extends Consumer Super)?) should really help you understand. There is a rule called PECS. Producer extends and consumer super. This rule should have been included in Java tutorial of wildcards because without this, the understanding of Bounded wildcards seemed incomplete to me.
It is essentially implying, that if you want to read only from a List (not write into it) , then use
List<? extends ParentClass>
it indicates that you will get objects which are subtypes of ParentClass or ParentClass. Also, implies that List is in read only mode.
And if you want to 'put' into a list not read from it, then by declaring your list as
List<? Super ParentClass>
you can add types that are either ParentClass or its types. But nothing else can be put in.
Also, wrote the following code and
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());
And Eclipse compile time errored out line # 4, 6, 7 and 10, 11, 12. This clearly indicates that super bound wildcards must be understood in context of read only and write only context.
Upvotes: 0
Reputation: 6457
The inheritance relationship is expressed as "is a": your SubClass
is a ParentClass
, and ParentClass
is a instance of its superclass, etc. So when coding you can always set a SubClass
anywhere a ParentClass
or any of its ancestors:
SubClass subClass = new SubClass();
ParentClass aParent = subClass;
Upvotes: 1
Reputation: 4937
The type List<? super ParentClass>
means "List of some unknown type that is at most ParentClass". If you had a method that accepted a parameter of this type, you could pass it something of type List<ParentClass>
, List<GrandparentClass>
, ..., List<Object>
...
void x(List<? super ParentClass> list) {
list.add(new SubClass());
}
Any lists of those types would admit a call to add
with a parameter of type SubClass
. So, regardless of the type of list
in method x
, the call to add
would preserve type safety.
Upvotes: 4