gpt4 book ai didi

java - 转换为通用变量

转载 作者:搜寻专家 更新时间:2023-10-30 21:33:23 25 4
gpt4 key购买 nike

我了解泛型和转换,但不了解泛型转换。我以为我只能通过继承树向上或向下转换为特定类型,但这证明我错了:

ArrayList<?> cislo = (ArrayList<? extends Number>) new ArrayList<Integer>();

这可能不是最好的例子,但希望你能明白我的意思。这是如何运作的?它被转换成什么类型​​?

最佳答案

Actor 是不必要的。

作业

ArrayList<?> list = new ArrayList<Integer>();
ArrayList<? extends Number> list2 = new ArrayList<Integer>();

不需要任何显式转换。

通配符类型比具体类型“更通用”/“更不具体”,upper bounded wildcard types (如 ? extends Number )比 unbounded ones 更具体(?)。

有关通配符类型之间关系的更多信息,请参阅 Oracle Tutorial on Wildcards and Subtyping .

指定它的 JLS 的相关部分是 4.10.2. Subtyping among Class and Interface Types

Given a generic type declaration C (n > 0), the direct supertypes of the parameterized type C, where Ti (1 ≤ i ≤ n) is a type, are all of the following:

  • D, where D is a generic type which is a direct supertype of the generic type C and θ is the substitution [F1:=T1,...,Fn:=Tn].
  • C, where Si contains Ti (1 ≤ i ≤ n) (§4.5.1).

[...]

指的是 4.5.1. Type Arguments of Parameterized Types

A type argument T1 is said to contain another type argument T2, written T2 <= T1, if the set of types denoted by T2 is provably a subset of the set of types denoted by T1 under the reflexive and transitive closure of the following rules (where <: denotes subtyping (§4.10)):

  • ? extends T <= ? extends S if T <: S

  • ? extends T <= ?

[...]

所以根据这个定义ArrayList<? extends Number>ArrayList<Integer> 的父类(super class)型和 ArrayList<?>是任何 ArrayList<> 的父类(super class)型除了原始类型。

为父类(super class)型类型的变量赋值不需要转换。


如果您想分配不同类型的东西,则需要强制转换:

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秒。如果您将其他内容分配给 list,则转换将在运行时失败不是 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

发生这种情况是因为在运行时,列表类型的删除匹配。另见 the tutorial on erasure

关于java - 转换为通用变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38452101/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com