Answering in 2022
Casting a List of supertypes to a List of subtypes is nonsensical and nobody should be attempting or even contemplating doing such a thing. If you think your code needs to do this, you need to rewrite your code so that it does not need to do this.
Most visitors to this question are likely to want to do the opposite, which does actually make sense:
Cast a list of subtypes to a list of supertypes.
The best way I have found is as follows:
List<TestA> testAs = List.copyOf( testBs ); This has the following advantages:
- It is a neat one-liner
- It produces no warnings
- It does not make a copy if your list was created with
List.of()!!! - Most importantly: it does the right thing.
Why is this the right thing?
If you look at the source code of List.copyOf() you will see that it works as follows:
- If your list was created with
List.of(), then it will do the cast and return it without copying it. - Otherwise, (e.g. if your list is an
ArrayList(),) it will create a copy and return it.
If your List<TestB> is an ArrayList<TestB> then a copy of the ArrayList must be made. If you were to cast the ArrayList<TestB> as List<TestA>, you would be opening up the possibility of inadvertently adding a TestA into that List<TestA>, which would then cause your original ArrayList<TestB> to contain a TestA among the TestBs, which is memory corruption: attempting to iterate all the TestBs in the original ArrayList<TestB> would throw a ClassCastException.
On the other hand, if your List<TestB> has been created using List.of(), then it is unchangeable(*1), so nobody can inadvertently add a TestA to it, so it is okay to just cast it to List<TestA>.
(*1) when these lists were first introduced they were called "immutable"; later they realized that it is wrong to call them immutable, because a collection cannot be immutable, since it cannot vouch for the immutability of the elements that it contains; so they changed the documentation to call them "unmodifiable" instead; however, "unmodifiable" already had a meaning before these lists were introduced, and it meant "an unmodifiable to you view of my list which I am still free to mutate as I please, and the mutations will be very visible to you". So, neither immutable or unmodifiable is correct. I like to call them "superficially immutable" in the sense that they are not deeply immutable, but that may ruffle some feathers, so I just called them "unchangeable" as a compromise.