The generic type parameter that Java infers from the call to Arrays.asList
is the common type of the arguments to asList
-- Integer
, so the new ArrayList
is an ArrayList<Integer>
, not an ArrayList<Double>
.
Java won't throw a ClassCastException
at List<Double> listD = (List<Double>) listI;
, because at runtime, type erasure has already happened, and to the JVM, the code looks like this:
List listD = (List) listI;
That is perfectly fine to the JVM.
The ClassCastException
comes later, from attempting to cast the Integer
that is really coming from casting the list to a Double
. With generics, the Java compiler will insert an implicit cast to the generic type parameter, in this case, Double
, when an item is retrieved. However, it's really an Integer
.
There should have been a warning, on the cast when you compiled this code, about an "unchecked cast" when casting the List<?>
to a List<Double>
. It warns you about the very possibility that you've demonstrated - a potential ClassCastException
later.