Let's start with a small example (note this uses raw types; and they are evil),
public static void main(String[] args) {
List<String> strings = Arrays.asList("Hello");
List<Integer> al = new ArrayList(strings);
for (Integer v : al) {
System.out.println(v);
}
}
It compiles. If we run it we get
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at com.stackoverflow.Example.main(Example.java:11)
Because String is not Integer. We can examine the bytecode with javap -v
35: invokeinterface #37, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
40: checkcast #43 // class java/lang/Integer
43: astore_3
44: getstatic #45 // Field java/lang/System.out:Ljava/io/PrintStream;
And see that the cast fails on the line numbered 40. Generic types are for compile time type checking, at run-time (almost) everything is an Object.