Ana M
Ana M

Reputation: 667

A simple clarification about Wild Cards in Java

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

Answers (4)

Johnny Willer
Johnny Willer

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

DolphinJava
DolphinJava

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

jalynn2
jalynn2

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

pholser
pholser

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

Related Questions