aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Generics wilcard Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Generics wilcard " Watch "Generics wilcard " New topic
Author

Generics wilcard

sentil kumar
Ranch Hand

Joined: Oct 23, 2006
Posts: 74
class Animal{ }
class Cat extends Animal{}
class Test{
public static void main(Stirng[] a){
List<? extends Animal> list = new ArrayList<Animal>();
list.add(new Animal()); // 1
list.add(new Cat()); // 2
}
}
please explain why both line 1 and 2 showing compile time error.
sentil kumar
Ranch Hand

Joined: Oct 23, 2006
Posts: 74
can anyone help me out
Maciej Zpolski
Greenhorn

Joined: Nov 02, 2006
Posts: 10
Hi,
first you must konw, that List<Cat> isn't subtype of List<Animal>
List<Animal> list = new ArrayList<Cat>() // error
but sometimes we need reference type, that can hold List<Animal>, List<Cat>,
List<Dog>, for example in methods paramether.
When we write List<? extends Animal>, we say to compiler: that reference can hold any List with any subtype of Animal.
And compiler say ok, but you cannot add any elements to list, because that instance could be ArrayList<Cat>, which can't hold Animal.

That's why we get error

But you can write
List<? super Animal> list= new ArrayList<Animal>();
list.add(Cat);
Think about it


Sorry for my english..
Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
Maciej Zpolski posted November 23, 2006 09:20 AM
But you can write
List<? super Animal> list= new ArrayList<Animal>();
list.add(Cat);

You can't add a Cat to a List<? super Animal>

Maybe look at this related thread

Not related:

Why do Cats have got eight tails?


1) No cat has seven tails.
2) One cat has one tail more than no cat.

from 1 and 2 follows
3) One cat has eight tails


Yours,
Bu.


---
bad quoting edited

[ November 23, 2006: Message edited by: Burkhard Hassel ]
[ November 23, 2006: Message edited by: Burkhard Hassel ]

all events occur in real time
Maciej Zpolski
Greenhorn

Joined: Nov 02, 2006
Posts: 10
Hi Burkhard
I think, that what I've written is correct.

List<? super Animal> list= new ArrayList<Animal>();
list.add(Cat);

We can add Animal and any of its subclasses.(Cat in this example)
We can't add Animal superclass:

List<? super Animal> list= new ArrayList<Animal>();
list.add(Object);// error
W. Salazar
Greenhorn

Joined: Apr 14, 2006
Posts: 7
hi everybody
When you see <? whatever> you can't add anything in the collection

but if you have something like this:
List<? super Animal> list= new ArrayList<Animal>();
'******************
addWhatEver(list);

public void addWhatEver(List a){
a.add(new programmer()); ==>allow me to add but with a Warning
}
Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
Hi ranchers,

Maciej Zpolski posted November 23, 2006 04:10 PM
Hi Burkhard
I think, that what I've written is correct.

List<? super Animal> list= new ArrayList<Animal>();
list.add(Cat);

Yes, you re perfectly right.

I was mixing it up.

You cannot add things that are higher in hierarchy than animals,
but cats are fine. A cat is an animal, and they fit into an animals list.


What you cannot put in this list are Objects as you wrote.


But what is trickier to understand:
You cannot put animals in a <? super Cat> list:

That's what I found strange in the first place.


Yours,
Bu.
Adrian Engler
Greenhorn

Joined: Sep 18, 2006
Posts: 29
I think to understand why objects of certain types can or cannot be added to a Collection referenced by a type with a wild card is to go back one step and look at what collections such reference types can refer to.

1. What types of collections can reference variables with wild cards refer to

If Cat extends Animal and Dog extends Animal and Animal only extends Object,
List<? extends Animal> can refer to objects of the type List<Animal>, List<Dog> or List<Cat> and List<other subtypes of Animal...>. List<? extends Cat> can refer to List<Cat> and List<subtypes of Cat...>, but not to List<Animal>.

List<? super Animal> can refer to List<Animal> or List<Object>, List<? super Cat> can refer to List<Cat>, List<Animal> and List<Object>.

2. What can be added to a collection with a specified generic type

The rules for what can be added to a collection with a specified generic type are simple: the objects must be of the specified type or of a subtype (i.e. there must be an is-a relation with the type specified as the generic type for the collection).
So, for instance, to a list of type List<Animal>, objects of types Animal, Cat or Dog can be added. To a list of type List<Cat>, objects of type Cat can be added.

3. What can be added to a collection referenced by a wild card type

a) <? extends ...>
A reference variable like List<? extends Animal>, it can refer to objects of the types List<Animal>, List<Cat>, List<Dog> or List<any other subtype of Animal...>. We don't know whether it refers to an object of the type List<Animal> or one of List<subtype of Animal...>.
If what we want is to call methods on the objects in the collection, that's fine - since the type of the objects in the collection must be Animal or a subtype of Animal, we can call all methods of Animal on the objects in the collection.
If, however, we want to add something to the collection, there's a problem: we don't know which subtype of Animal the reference variable will refer to, therefore we cannot know what we are allowed to add to the collection. For instance, if we have a reference variable of the type List<? extends Animal>, it may refer to an object of the type List<Cat> - then we would be allowed to add cats, but not dogs - or it may refer to an object of type List<Dog> - then we would be allowed to add dogs, but not cats. There is no way to know at compile time, therefore it is not allowed to add anything to a collection referenced by a reference type of List<?> or List<? extends ...>.

b) <? super ...>
List<? super Cat> may refer to List<Cat>, List<Animal> or List<Object>. We know that we are allowed to add objects of type Cat because in every case, Cat is either the generic type of the collection or a subtype of it.
However, we are not allowed to add objects of type Animal because List<? super Cat> may refer to an object List<Cat> and objects of type Animal cannot be added to List<Cat>. Objects of type Object may not be added because List<? super Cat> may refer to a list of the type List<Animal> or List<Cat>, in both cases it is not acceptable to add objects of type Object.
The only thing that is safe to add to a collection referenced to by a variable of the type <? super Cat> is objects of type Cat or any subclasses of Cat.


SCJP 5.0 (93%), SCWCD (98%), SCJD (377/400), SCBCD (100%)
Karen Marie
Greenhorn

Joined: Nov 10, 2007
Posts: 23
This post is over a year old but Adrian's explanation was sooooo helpful to me for solidifying what I just read in K&B chapter 7.

If someone were clarifying the following in the same way as numbers 4 and 5 on his list, how would they explain what is allowed for

4. <T extends Animal>
5. <T super Animal>

I've also read that it means different things for methods vs class definitions but don't really understand how.
nico dotti
Ranch Hand

Joined: Oct 09, 2007
Posts: 124
Yeah, Adrian's post is helpful. I'd sum it up that in general, when you use: <? extends SomeObject> you can't add ANYTHING! Whereas, the <? super SomeObject> does let you add as long as it's a subclass of 'SomeObject'. The tricky thing here that's counterintuitive is the what you reference and what you can add are opposite ( you can reference SomeObject or it's Parents while you can only add SomeObject or it's Children) When I burn into my mind that the first doesn't allow adding, I seem to remember the fact that you can only add Foo or Foo's children with the <? super Foo> version. So I read it take Foo or higher but only allows adding Foo or lower :roll:
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Generics wilcard