这就是泛型在 Java 中的工作方式。String 类实现接口 CharSequence,但不能将 List<CharSequence> 强制转换为 List<String>(反之亦然)。但是您可以将 ArrayList<String> 转换为 List<String> (并将 List<String> 转换为 ArrayList<String> - 至少编译器不会抱怨,但如果您的 List 对象不是实例,您将获得运行时异常数组列表)。
如果有可能呢?这是一个例子:
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!
这就是为什么第 2 行出现编译错误的原因。当然,您可以欺骗编译器并尝试以下操作:
A<I> myobj = null;
A genericA = new B();
myobj = (A<I>) genericA;
这将起作用,因为在运行时中删除了泛型类型。您也可以使用列表执行此操作:
List<String> listOfStrings = new ArrayList<String>();
List genericList = listOfStrings;
genericList.add(new Object());
String s = listOfStrings.get(0);
此代码将编译(带有警告),但您将在运行时遇到异常:
Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.String
这段代码:
myobj = (A<I>) Class.forName("B").newInstance();
有效,因为方法newInstance()返回 java.lang.Object 的一个实例。编译器不知道它将在运行时返回什么,因此它允许将其转换为所有内容。由于Type Erasure,在运行时 A<I> 只是 A,并且由于 B 是 A 的子类,您可以将 B 的实例强制转换为 A。