File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Generic methods and wildcards Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Generic methods and wildcards" Watch "Generic methods and wildcards" New topic
Author

Generic methods and wildcards

Katrin Perry
Ranch Hand

Joined: Mar 07, 2007
Posts: 60
Hi,

This is an extrace of the guide published in: http://java.boot.by/scjp-tiger/ch06s04.html

"As an example of using wildcards, consider a draw() method that should be capable of drawing any shape such as circle, rectangle, and triangle. The implementation may look something like this. Here Shape is an abstract class with three subclasses: Circle, Rectangle, and Triangle:




It is worth noting that the draw(...) method can only be called on lists of Shape and cannot be called on a list of Circle, Rectangle, and Triangle for example. In order to have the method accept any kind of shape, it should be written as follows:


"

When I tried this, providing Shape isn't an abstract class, both draw functions behaved exactly the same.

Could anyone explain, why it is expected that they would not. particularily I am not clear about the statment in bold.

Thanks
Katrin


Katrin
SCJP 5.0, SCWCD, SCBCD
Collins Mbianda
Ranch Hand

Joined: Aug 11, 2007
Posts: 259
hi !!!

? estends Shape means: The class Shape or any subclass of Shape.

Calling the two methods with a Shape instance will have the same result.

Note that a List<Rectangle> is not a List<Shape> even if a Rectangle is a Shape.

You cannot call the method draw(List<Shape> shape) with a list of Rectangle List<Rectangle>. The following code will not compile


But you can call the method draw(list< ? extends Shape> shape) with a list of any subclass of a Shape
You can call the method with a List<Rectangle>. The following code will compile.



Hope i clear your doubt.
[ September 15, 2007: Message edited by: Collins Mbianda ]

SCJP 5.0 | SCWCD 1.4
Brandon Bay
Greenhorn

Joined: Aug 31, 2007
Posts: 29
Howdy all,

I'm having trouble with Generics too, so instead of creating a similiar topic, I shall post my problems here.

Given :



For #1,#2,#3 and #4, my doubts are why the List< ? super A > was able to add a B inside. Is it because it is allowed for any subtype of A to be added too? Also, #4 gives a COMPILATION error !! Why? Doesnt A extends Object? Object is a superclass of A.

For #5 and #6, the list was specified as <? extends A>, means ANYTHING which is A or subclass of A can be added. But how come when I add a A , it refuses to compile?


Hope to get cleared here. My exam's less than 2 days time. I'm really getting nervous. Haha.

[ September 15, 2007: Message edited by: Brandon Bay ]
[ September 15, 2007: Message edited by: Brandon Bay ]
Collins Mbianda
Ranch Hand

Joined: Aug 11, 2007
Posts: 259
Hi!!!



From K&B Book(page 593) :
By List<? extends Animal> we're saying: " I can be assigned a collection that a subtype of List and typed for<Animal> or anything extends Animal. And oh yes, I SWEAR that will not ADD anything into the collection."

For that reason you cannot add an element to your list:


You will get a compile error at #6.

When you use the < ? super ...> syntax, you are telling the compiler that you can accept the type on the right hand side of super or any of it supertypes,


new A() is an instance of A. That why #2 compile.
new B() is an instance of A since B extends A. That why #3 compile.
new Object() is not an instance of A. That why #4 don't compile.

Hope i clear your doubt.
Good luck for the exam.
[ September 15, 2007: Message edited by: Collins Mbianda ]
Brandon Bay
Greenhorn

Joined: Aug 31, 2007
Posts: 29
i see.. thanks for your feedback and well wishes Collins
Katrin Perry
Ranch Hand

Joined: Mar 07, 2007
Posts: 60
Thank you it is a lot clearer now. I have my test in 4 days.
Katrin
Collins Mbianda
Ranch Hand

Joined: Aug 11, 2007
Posts: 259
Good luck to both of you.
Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
Sorry, is a bit long...

To Katrin:

On the other hand, you can use the method as it is with List<Shape>.
There is no problem to stuck a (e.g.) Triangle into this list, because a Triangle IS-A Shape (and has got the draw() method).

The extended version is only needed if you really have to deal with pure lists of Triangle, Rectangle, Circle.



Katrin:

When I tried this, providing Shape isn't an abstract class, both draw functions behaved exactly the same.

They are not the same, as Collins already explained.
I don't know why you don't want Shape to be abstract. Should work fine as well.

To explain:
Just for drawing Circles, Rects etc. you do NOT need a List<? extends Shape>.
A List<Shape> should be enough:

prints a lot of circles, rectangles and triangles.


Only when you e.g. have a method that returns a List<Triangle> then the drawAll does not work.
Then you would either stuff the List<Circle> into a new List<Shape> or use the "extended version":

This will compile without warnings and prints rects and tris twice.


Yours,
Bu.


all events occur in real time
Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
To Brandon:

What Collins wrote can be a bit misleading:
When you use the < ? super ...> syntax, you are telling the compiler that you can accept the type on the right hand side of super or any of it supertypes, ...



If Collins were right, you would be able to add and Object() into such a list, because Object is the supertype of everything. But you can't.


So generally:
List<? extends YourClass> variable;
You can assign a list of anything that extends YourClass (and YourClass itself) to this variable.
You can add nothing to that class. Is read-only. Exception: you can add null.

List<? super YourClass> variable;
You can assign a list of YourClass or anything higher in hierarchy (including List<Object> to this variable.

Assigning a list higher in hierarchy also means, that this list may already contain objects higher in hierarchy without problems.
You can also add objects (small o) of type MyClass to this list.
But: You can not add objects higher than type "YourClass" to this list directly.
And: What you get out of this list is of type Object, not YourClass.

prints something like [java.lang.Object@10b62c9, a String, null].

Of course you can add "lower" types to this kind of lists cause for any Collection<MyClass> you can add subclasses of MyClass. The object behind can surely be lower, because of polymorphy the same as when you can e.g. say:
Object x = new Integer(5);






To all:
Good luck!


Yours,
Bu.
Katrin Perry
Ranch Hand

Joined: Mar 07, 2007
Posts: 60
Burkhard,

I am now a bit confused with your explanations to Brandon.

Why in the last code example:



wouldn't compile? I mean, I tried it and it really doesn't

I am just not clear at all why.

Great explanation to my Generics problem, thanks.


Brandon good luck to you!
Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
You are absolutely right, this is puzzling.


List<Object> objList = new ArrayList<Object>();
objList.add(new Object());

List<? super String> superList = objList; // fine


This <? super String> can be referred to Lists of String and all the hierarchy up to Object (ok, there is only class Object higher than String because String extends Object directly). As in the example, the superList can contain also Objects.
You can also code:
List<? super String> superList = new Vector<Object>();

In the upper example, the array list already contained an Object (big O), but that is ok since what you get out of that list will always be of type Object (not String!).


A List<? super String> may contain lists of type String and any higher type.
But you can add directly only Strings, nothing higher.
These difference is what puzzles people.





This has to be that way.
When you have a



you are allowed to assign two kinds of lists to it:
List<String> or List<Object>. (ok, not Lists themself, cause they are interfaces and can't be instanciated).

The compiler has to assure, that you add only things that fit in.
It does not know, if you later assign a List<String> or a List<Object> to that variable.
Therefore it allows only to add directly the highest type possible of the lowest type a list can have that is referred by this variable.
Lowest type possible is String, therefore only Strings can be allowed to be added directly.
But the lists assigned to that variable can be Strings or higher.


Phew.

Yours,
Bu.
Collins Mbianda
Ranch Hand

Joined: Aug 11, 2007
Posts: 259
Thanks Burkhard for all these explanations.
We were making confusion on how to insert elements within
a List< ? super ...>

We will remenber what you say:
A List<? super String> may contain lists of type String and any higher type.
But you can add directly only Strings, nothing higher.
Katrin Perry
Ranch Hand

Joined: Mar 07, 2007
Posts: 60
Thanks I would try to remember.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Generic methods and wildcards
 
Similar Threads
up cast of object
what is polymorphic arguments ???
Questions about polymorphism and interfaces
Understanding abstract methods
Generics: Shape example does not work as SUN says