Jump to content

JAVA - wildcards and generic methods

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
2 replies to this topic

#1
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
I'm going trough this tutorial: Wildcards (The Java™ Tutorials > Bonus > Generics)

And i understand all of it pretty well.
I'm just a bit confused about the following (orange part is most important if you want to skip a bit of reading):
What we really want is for the method to accept a list of [B]any[/B] kind of shape:[INDENT][B]public void[/B] drawAll(List<? [B]extends[/B] Shape> shapes) {
    ...
}
[/INDENT]There is a small but very important difference here: we have replaced the type  List<Shape> with List<? [B]extends[/B] Shape>. Now drawAll() will accept lists of any subclass of Shape,
so we can now call it on a List<Circle> if we want.   List<? [B]extends[/B] Shape> is an example of a [I]bounded wildcard[/I]. 
The ? stands for an unknown type, just like the wildcards we saw earlier. However, in this case, we know that this unknown type is in fact a subtype of Shape. 
(Note: It could be Shape itself,  or some subclass; it need not literally extend Shape.)   We say that Shape is the  [I]upper bound[/I] of the wildcard. 
  
[COLOR=DarkOrange]There is, as usual, a price to be paid for the flexibility of using  wildcards. That price is that it is now illegal to write into shapes in the body of the method. For instance, this is not allowed:[/COLOR][INDENT][COLOR=DarkOrange][B]public void[/B] addRectangle(List<? [B]extends[/B] Shape> shapes) {
    shapes.add(0, [B]new[/B] Rectangle()); // [I]Compile-time error![/I]
}
[/COLOR] [/INDENT][COLOR=DarkOrange]You should be able to figure out why the code above is disallowed. The type of the second parameter to shapes.add() is ? [B]extends[/B] Shape
--  an unknown subtype of Shape. Since we don't know what type it is, we don't know if it is a supertype of Rectangle; it might or might not be such a supertype, so it isn't safe to pass a Rectangle there. [/COLOR]
(Note that >>Rectangle extends Shape in the tutorial<<. )

And especially this part:
>
Since we don't know what type it is, we don't know if it is a supertype of Rectangle; it might or might not be such a supertype, so it isn't safe to pass a Rectangle there. 
Is there anyone who does understand what they mean there and cares to attempt to explain again or give a small example how that would turn wrong? ("if it might"):confused:

(I took code tags as i found them easier to read)

#2
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
Basically, it's saying you can use ANY subclass of Shape, rather than being forced to use something that is exactly Shape. In this case, you could store Rectangle, Triangle, or Circle in the List, but NOT Widget, Blue, or Purple.
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#3
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
ye tthat's what the wildcard does indeed. but i was wondering why you can't add a rectangle to this List:

public void addRectangle(List<? extends Shape> shapes) { 
    shapes.add(0, new Rectangle()); // Compile-time error!
}
explanation they give is

Quote

Since we don't know what type it is, we don't know if it is a supertype of Rectangle; it might or might not be such a supertype, so it isn't safe to pass a Rectangle there.
But i don't understand it, and i don't see a case where there would be a list of type x extends Shape where you would be unable to add a Rectangle object.


Edit: oh ****, that's actually pretty simple. For some reason i always thought that shapes == List<Shape>, while it ofcourse doesn't ^^

Edited by wim DC, 22 July 2010 - 10:28 PM.