[英]Why is it possible to cast generic class?
Java 泛型是不变的,所以不可能进行这样的转换:
List<Object> li = (List<Object>)new ArrayList<Integer>();
但是在第 4 行的以下代码中,我可以从List<Integer>
为List<T>
,其中T
可以是任何类型。 为什么允许这种类型的演员表?
我知道它会生成有关未经检查的强制转换的警告,但关键是这种强制转换在参数化方法中是可能的,但在普通代码中是不可能的。 记住泛型是不变的,为什么允许它? 在具有List<Integer>
普通代码中,我只能将其转换为List<Integer>
,这没有意义,其他转换是非法的。 那么允许像第 4 行那样进行强制转换有什么意义呢?
我知道泛型类型在编译时被删除,它以List xlist = (List)list
结尾,但在删除这些类型之前,很明显不应允许这种强制转换,除非它仅在有人通过 Integer 作为的情况下被接受el
没有多大意义。
class Test {
public static <T> void t(List<Integer> list, T el) {
List<T> xlist = (List<T>)list; //OK
xlist.add(el);
}
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
t(list, "a");
t(list, "b");
//prints [a, b] even if List type is Integer
System.out.println(list);
}
}
在 Java 中,执行在编译时已知始终不正确或始终正确的显式强制转换是编译错误。 在编译时已知从List<Integer>
到List<Object>
转换总是不正确的,因此这是不允许的。 从List<Integer>
到List<T>
在编译时并不知道总是不正确的——如果T
是Integer
则是正确的,而T
在编译时不知道。
我想答案是这个转换是可能的,因为Integer
可以作为参数el
传递,在这种情况下,转换是正确的。 在 Integer 以外的所有其他类型的情况下,它将是非法转换。 但是正如我在泛型中看到的那样,如果至少有一种类型可以提供正确的转换( Integer
),那么编译器不会给出错误,而是警告,即使所有其他情况都无效。
Object 是 Integer 类的超类。 List<Object>
不是List<Integer>
类的超类,但此外,如果您希望List<Object>
引用List<Integer>
您可以使用小丑符号 (?)。
List<?> list1 = new List<Object>();
List<?> list2 = new List<Integer>();
list1 = list2;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.