• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Casting Around In Generics

 
Jack J. Jackson
Greenhorn
Posts: 27
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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 ]
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24208
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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!
 
Jack J. Jackson
Greenhorn
Posts: 27
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Sheriff
Pie
Posts: 20739
30
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic