繁体   English   中英

转换为泛型变量

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM