| Author |
Casting Around In Generics
|
Jack J. Jackson
Greenhorn
Joined: Apr 20, 2002
Posts: 27
|
|
I've been working with Java 5.0 generics for awhile, but am not sure about a casting issue. Consider the following code: Since Foo implements FooI, I can cast a FooI reference to a Foo object reference. However, the following implementation of Foo will not work: The compiler complains that we cannot convert from List<FooI> to List<Foo>. However, if we iterate across the List of FooI, we can cast each member to a Foo, as in: Call me dense, but I'm not sure why I can't cast from a List<FooI> to a List<Foo> if I can cast each member of the list to the other type? Thanks for getting me back on track. [ April 20, 2006: Message edited by: Jack J. Jackson ]
|
Jack
|
 |
Ernest Friedman-Hill
author and iconoclast
Marshal
Joined: Jul 08, 2003
Posts: 24061
|
|
A List<Fool> could validly contain instances of Foo2, Foo3, etc -- other classes that also implement Fool. If the cast were to succeed, then have to get errors later on, where they'd be unexpected. If things worked that way, then any call to get(i) (for example) on a List<Foo> could throw a ClassCastException -- not a pretty prospect. Therefore, by definition, a List<Fool> can't be cast to a List<Foo>, nor vice-versa. In a way, this is an attempt to make up for they mistake they made when they defined an inheritance relationship between Java array types. This is legal (but disastrous!) String[] foo = {"a", "b", "c"}; Object[] bar = foo; bar[0] = new Integer(3); // ArrayStoreException!
|
[Jess in Action][AskingGoodQuestions]
|
 |
Jack J. Jackson
Greenhorn
Joined: Apr 20, 2002
Posts: 27
|
|
Sorry to be so late in thanking you for the response. I understand the reason you offered, but will have to mark this as a language behavior to know, but not necessarily like. The argument that a ClassCastException could occur later when accessing the (improperly) cast list makes sense, but it's in the nature of downcasting that the developer is assuming responsibility that the cast is semantically valid after the compiler ensures it is syntactically valid. So, we say the following cast isn't valid since a later access of list could cause an unexpected ClassCastException... However, the same unexpected ClassCastException could occur even without the list cast: However, I take your point that if I call the get() on a List<Foo>, I really expect only Foo object references will be in there, whereas calling the get() on a List<FooI> provides less certainty as to what the "true object at hand" really is. Thanks again! [ June 22, 2006: Message edited by: Jack J. Jackson ]
|
 |
Paul Clapham
Bartender
Joined: Oct 14, 2005
Posts: 16483
|
|
Since Foo implements FooI, I can cast a FooI reference to a Foo object reference.
Sure you can. But that might throw a ClassCastException, because the FooI reference might be to a FooBar object that isn't a subclass of Foo. And since the main point of Generics is to prevent ClassCastExceptions by compile-time analysis, you get the message that the cast is unsafe.
Call me dense, but I'm not sure why I can't cast from a List<FooI> to a List<Foo> if I can cast each member of the list to the other type?
Okay, you asked for it. You're dense You can't cast each member of the list to the other type.
|
 |
 |
|
|
subject: Casting Around In Generics
|
|
|