aspose file tools*
The moose likes Java in General and the fly likes Casting Around In Generics Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Casting Around In Generics" Watch "Casting Around In Generics" New topic
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: 24187
    
  34

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: 18991
    
    8

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.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Casting Around In Generics