38

Suppose class B extends class A. I have a List<A> that I happen to know only contains instances of B. Is there a way I can cast the List<A> to a List<B>?

It seems my only option is to iterate over the collection, casting one element at time, creating a new collection. This seems like an utter waste of resources given type erasure makes this completely unnecessary at run-time.

Landon Kuhn
  • 61,957
  • 42
  • 100
  • 130
  • 2
    Thank you everybody for the good answers. Casting to a List is the most appropriate solution in this case. I am willing to sacrifice type safety for performance in this case. – Landon Kuhn Oct 30 '09 at 17:52

4 Answers4

48

You can cast through the untyped List interface:

List<A> a = new ArrayList<A>();
List<B> b = (List)a;
jarnbjo
  • 32,366
  • 6
  • 65
  • 87
17

You can try this :

List<A> a = new ArrayList<A>();
List<B> b = (List<B>) (List<?>) a;

It is based on the answer of jarnbjo, but on don't use raw lists.

Romain
  • 1,065
  • 10
  • 8
1

A way to retain some type safety with minimum impact on performance is to use a wrapper. This example is about Collection, the List case would be very similar and maybe one day I'll write that too. If someone else comes before me, please let's share the code.

zakmck
  • 2,022
  • 27
  • 37
1

List<A> is not a subtype of List<B>!

The JLS even mentions that explicitly:

Subtyping does not extend through generic types: T <: U does not imply that C<T> <: C<U>.

Joachim Sauer
  • 278,207
  • 54
  • 523
  • 586