This is the way generics work in Java. Class String implements interface CharSequence, but you can't cast List<CharSequence> to List<String> (or vice versa). But you can cast ArrayList<String> to List<String> (and List<String> to ArrayList<String> - at least compiler won't complain, but you'll get a runtime exception if your List object isn't an instance of ArrayList).
What if it were possible? Here's an example:
1. List<String> listOfStrings = new ArrayList<String>(); // piece of cake!
2. List<Object> listOfObjects = (List<Object>) listOfString; // String is a subclass ofObject, so why not?
3. listOfObjects.add(new Object()); // obviously correct
4. String s = listOfString.get(0); // ouch! We've just put an Object into this list, but generic type promises there are only Strings!
This is why there's a compilation error in line 2. Of course, you can fool the compiler and try this:
A<I> myobj = null;
A genericA = new B();
myobj = (A<I>) genericA;
This will work because generic types are removed in the runtime. You can do this also with lists:
List<String> listOfStrings = new ArrayList<String>();
List genericList = listOfStrings;
genericList.add(new Object());
String s = listOfStrings.get(0);
This code will compile (with warnings), but you will get an exception in the runtime:
Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.String
This code:
myobj = (A<I>) Class.forName("B").newInstance();
works, because method newInstance() returns an instance of java.lang.Object. Compiler has no idea what it will return in the runtime, so it allows casting it to everything. Because of the Type Erasure, in the runtime A<I> is just A, and since B is a subclass of A, you can cast an instance of B to A.