Assuming two classes A and B as
class A {} class B extends A {}
It is just logical that casting B to A works fine:
A anObjectOfClassA = new B();
But when it comes to collections of As and Bs, a strange phenomenon appears in Java:
Collection<B> collectionOfBs = new LinkedList<B>(); Collection<A> collectionOfAs = (Collection<A>)collectionOfBs; // this line does not compile!
That is, though the collection wrapper (the java.util.Collection class) is the same and B extends A, casting a collection of objects of class B to a collection of objects of class A throws an compile-time error.
But it works using generics (the whole class for the sake of completeness and reusability):
import java.util.Collection; import java.util.LinkedList; public class CollectionCastingExample { class A {} class B extends A {} Collection<B> collectionOfBs = new LinkedList<B>(); // Collection<A> collectionOfAs = (Collection<A>)collectionOfBs; Collection<A> collectionOfAs = downCastCollection(collectionOfBs, A.class); /** * Casts a collection of objects of class B where B extends A to a collection of objects of class A. * * @param <T> Base class * @param collection Collection of objects of a class extending T * @param aClass Representation of T * @return Collection of objects of T casted from given collection of objects of a class extending T. */ @SuppressWarnings("unchecked") public static <T> Collection<T> downCastCollection(Collection<? extends T> collection, Class<T> aClass) { return (Collection<T>) collection; } }
Despite the fact that a @SuppressWarnings("unchecked")
is required, it avoids iterating over the whole collection of Bs and casting each of them from B to A plus adding them to a new collection of As.