Re: Generic type cast involving wildcard type
On Thu, 30 Jul 2009, Daniel Thoma wrote:
What I know from literature is something like this:
List<?> list = new List<String>();
list.add(list.get(0)); // fails
foo(list); // works
void <T> foo(List<T> list) {
list.add(list.get(0));
}
And in this case, I can follow, because the compiler would have to transport
the information, that he is dealing with one list (with a fixed but unknown
type) in both parts of the expression. And it is not so easy to guarantee,
that "list" doesn't change its value in between.
If it's a local variable, it's pretty easy, and the kind of thing
compilers do all the time. Less so if it's an instance variable, true.
In the casting scenario I can not realy follow that explanation. As I see
it, there aren't even two capture variables involved.
There aren't - there are three.
List<?> high = new ArrayList<String>();
// ^ one
ArrayList<?> low = (ArrayList<?>)high;
// ^ two ^ three
I think the compiler could work out that this is safe - it could look at
the relatioship between the type variable in ArrayList and the one in
List, see that they're defined to be the same (by "ArrayList<E> implements
List<E>"), and deduce that the variables on high and low are the same.
I don't know that this would be a good idea, though. If you have two
variables bound to the same type, why not make that explicit by
introducing a type variable?
List<Q> high = new ArrayList<String>();
ArrayList<Q> low = (ArrayList<Q>)high;
The problem with this is that the only way to define a type variable is to
add it to the method signature. What would be useful is if we could
define them locally. Like:
type <Q>;
List<Q> high = new ArrayList<String>();
ArrayList<Q> low = (ArrayList<Q>)high;
Or something. Or maybe scoped to blocks (weird syntax alert!):
<Q> {
List<Q> high = new ArrayList<String>();
ArrayList<Q> low = (ArrayList<Q>)high;
}
Typically, though, this is a non-issue, since the ?-typed thing you're
operating on is coming in as a method parameter or something anyway, and
you can set up a type variable there.
The example code you posted was obviously contrived. What was your real
code? Can we see how we might solve the real problem?
tom
--
I prefer gin now sleep doesn't want me anyway.