[英]Casting to generic variable
我理解通用和铸造,但我不懂通用铸造。 我以为我只能通过继承树向上或向下投射特定类型,但这证明我错了:
ArrayList<?> cislo = (ArrayList<? extends Number>) new ArrayList<Integer>();
这可能不是最好的例子,但希望你能得到我的观点。 这是如何运作的? 它的演员类型是什么?
演员是不必要的。
作业
ArrayList<?> list = new ArrayList<Integer>();
ArrayList<? extends Number> list2 = new ArrayList<Integer>();
不需要任何明确的投射。
通配符类型是“更普遍的” /“较不具体的”类型比混凝土的类型,和上界通配符类型 (如? extends Number
)比更具体的无界的人 ( ?
)。
有关通配符类型之间关系的更多信息,请参阅Oracle Tutorial on Wildcards和Subtyping 。
JLS的相关部分指定为4.10.2。 类和接口类型之间的子类型
给定泛型类型声明C(n> 0),参数化类型C的直接超类型,其中Ti(1≤i≤n)是一种类型,是以下所有:
- D,其中D是泛型类型,它是泛型类型C的直接超类型,θ是替换[F1:= T1,...,Fn:= Tn]。
- C,其中Si含有Ti(1≤i≤n)(§4.5.1)。
[...]
这是指4.5.1。 输入参数化类型的参数
类型参数T1被称为包含另一个类型参数T2,写为T2 <= T1,如果由T2表示的类型集合可证明是在以下规则的反身和传递闭包下由T1表示的类型集的子集(其中<:表示子类型(§4.10)):
? 扩展T <=? 如果T <:S,则扩展S.
? 扩展T <=?
[...]
所以通过这个定义ArrayList<? extends Number>
ArrayList<? extends Number>
是ArrayList<Integer>
的超类型, ArrayList<Integer>
ArrayList<?>
是除原始类型之外的任何ArrayList<>
的超类型。
赋值为超类型的变量不需要强制转换。
如果要分配不同类型的内容,则需要强制转换:
Object list = new ArrayList<Integer>();
//...somewhere else - the compiler does not know that list is always an ArrayList, but we tell it that we know what we are doing
List<? extends Number> numbers = (List<? extends Number>) list; //unchecked cast warning, but works
在演员之后,您可以例如从列表中获取元素并将其视为Number
s。 如果你为list
引用分配了一些不是List<? extends Number>
的子类型,那么转换会在运行时失败List<? extends Number>
List<? extends Number>
Object list = new HashSet<Integer>();
List<? extends Number> numbers = (List<? extends Number>) list; //unchecked cast warning
在运行时抛出失败
java.lang.ClassCastException: java.util.HashSet cannot be cast to java.util.List
当泛型类型不匹配时,问题开始出现:
List<String> stringList = new ArrayList<String>();
stringList.add("hi");
Object list = stringList;
List<? extends Number> numbers = (List<? extends Number>) list; //unchecked cast warning, but (sadly) works
Number n = numbers.get(0); //fails: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number
发生这种情况是因为在运行时,列表类型的擦除匹配。 另请参阅有关擦除的教程
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.