Results 1 to 8 of 8
Thread: Generics and wildcards confusion
- 02-23-2011, 01:53 AM #1
Member
- Join Date
- Aug 2009
- Posts
- 26
- Rep Power
- 0
Generics and wildcards confusion
Hey I was reading this tutorial:
Wildcards (The Java™ Tutorials > Bonus > Generics)
and I don't get why the following throws a compile-time error.
"The type of the second parameter to shapes.add() is ? extends 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. "Java Code:public void addRectangle(List<? extends Shape> shapes) { shapes.add(0, new Rectangle()); // Compile-time error! }
If shapes is a list of unknown types which extend Shape, and it is known that Rectangle extends shape, then why is there a compile time error?
Cheers,
newbie
- 02-23-2011, 02:35 AM #2
Let me test your undestanding. The following code compiles but can you tell me what the problem with it is?
Java Code:public void doStuff(List<?> things) { XX foo = (XX) things.get(0); }
- 02-23-2011, 03:06 AM #3
Member
- Join Date
- Aug 2009
- Posts
- 26
- Rep Power
- 0
Reply to junky
I'm guessing that it won't compile as the datatype is unknown and you can't typecast it to XX as you don't know whether ? is a subtype of XX or of type XX itself.
- 02-23-2011, 03:07 AM #4
Member
- Join Date
- Aug 2009
- Posts
- 26
- Rep Power
- 0
sorry misread that
i read it as it doesn't compile...so how does that work then?
- 02-23-2011, 03:19 AM #5
Member
- Join Date
- Aug 2009
- Posts
- 26
- Rep Power
- 0
Get the problem junky i think
I think i get what the problem will be as i outlined in the previous message, i understand that it would work if 'things' contained a list of items which "could" be cast to XX but if it didn't then it would fail. right?
- 02-23-2011, 03:21 AM #6
The code does compile as each of those three lines are syntactically correct. The compiler is generally dumb as it doesn't look at more than a single line of code at once. A more common problem people encounter is
That does not compile as it is missing a return statement. To you and me we can see that it HAS to return 42 because it enters the if statement. Compiler says NO. All it knows is that it gets to the end of the method and there is no return statement.Java Code:public int doStuff() { if(true) { return 42; } }
So getting back to my code, it compiles. However at run time if I pass a List containing anything other than XX objects you will get a ClassCastException at runtime.
For the code you asked about the reverse is true. The compiler doesn't really care that Rectangle extends Shape. All it knows is that there is a potential that code can be written that will fail. For example, if that code DID compile then the following will also compile:
Even though those other classes don't(shouldn't) extend Shape. Therefore the compiler avoids potentially bad code.Java Code:public void addRectangle(List<? extends Shape> shapes) { shapes.add(0, new Rectangle()); shapes.add(0, new Cow()); shapes.add(0, new Cheesecake()); shapes.add(0, new Foo()); }
- 02-23-2011, 03:30 AM #7
Member
- Join Date
- Aug 2009
- Posts
- 26
- Rep Power
- 0
Moral of story is compiler is stupid lol
So basically the compiler never does any form of investigation on relationships between classes, hence even though Rectangle DOES extend Shape, it has a cry. Thanks for clearing that up, your examples were really good.
If I hadn't read your explanation of:
I would have assumed that the compiler would only throw errors for those statements in which the object being created DID NOT extend Shape..Java Code:public void addRectangle(List<? extends Shape> shapes) { shapes.add(0, new Rectangle()); shapes.add(0, new Cow()); shapes.add(0, new Cheesecake()); shapes.add(0, new Foo()); }
Thanks
- 02-23-2011, 03:37 AM #8
I just blathered on a bit and realised I could explain it much simpler with a code snippet.
Hopefully that really hits home the potential disaster.Java Code:public void addRectangle(List<? extends Shape> shapes) { shapes.add(0, new Rectangle()); // Compile-time error! } List<Circle> shapeList = new ArrayList<Circle>(); addRectangle(shapeList);
Similar Threads
-
Type wildcards in Generic
By gvm in forum New To JavaReplies: 1Last Post: 10-22-2010, 04:39 PM -
Confusion here @@' Help!
By pleasurelyours in forum New To JavaReplies: 7Last Post: 06-09-2010, 03:42 PM -
Confusion in line
By JavaJunkie in forum New To JavaReplies: 1Last Post: 06-13-2009, 10:46 PM -
Tic Tac Toe confusion
By jigglywiggly in forum New To JavaReplies: 15Last Post: 04-12-2009, 01:47 AM -
Generics and Wildcards
By ajeeb in forum Advanced JavaReplies: 2Last Post: 01-30-2009, 11:00 PM


LinkBack URL
About LinkBacks
Reply With Quote
Bookmarks