当前位置: 首页 > 面试题库 >

ArrayList.toArray()中的Java泛型

戚鸿
2023-03-14
问题内容

假设您有一个arraylist定义如下:

ArrayList<String> someData = new ArrayList<>();

稍后在代码中,由于泛型,您可以这样说:

String someLine = someData.get(0);

而且编译器完全知道它将得到一个字符串。是的仿制药!但是,这将失败:

String[] arrayOfData = someData.toArray();

toArray()将始终返回对象数组,而不是已定义的泛型数组。为什么该get(x)方法知道返回的内容,但toArray()默认为Objects?


问题答案:

如果你看一下执行toArray(T[] a)的的ArrayList

类,它是这样的:

public <T> T[] toArray(T[] a) {
    if (a.length < size)
        // Make a new array of a's runtime type, but my contents:
        return (T[]) Arrays.copyOf(elementData, size, a.getClass());
    System.arraycopy(elementData, 0, a, 0, size);
    if (a.length > size)
        a[size] = null;
    return a;
}

这种方法的问题是您需要传递相同泛型的数组。现在考虑如果此方法不带任何参数,则实现将类似于以下内容:

public <T> T[] toArray() {
    T[] t = new T[size]; // compilation error
    return Arrays.copyOf(elementData, size, t.getClass());
}

但是这里的问题是, 您不能在Java中创建通用数组, 因为编译器不知道确切T代表什么。换句话说 在Java中不允许
创建非可校正类型的数组
(JLS§4.7)。

数组存储异常
(JLS§10.5)中的另一个重要报价:

如果数组的组件类型不可修改(第4.7节),则Java虚拟机将无法执行上一段所述的存储检查。
这就是为什么禁止使用不可修改元素类型的数组创建表达式的原因(第15.10.1节)。

这就是Java提供重载版本的原因toArray(T[] a)

我将重写toArray()方法以告诉它它将返回E数组。

因此toArray(),您应该使用而不是覆盖toArray(T[] a)

无法从Java
Doc
创建类型参数的实例可能对您也很有趣。



 类似资料:
  • 问题内容: 我想知道为什么他们在Java中设计方法来接受数组的输入? 在我看来,他们不需要此输入,因为ArrayList实例本身具有足够的详细信息以将数据转换为数组。 我的问题是为什么他们仍然需要传递数组?谢谢。 问题答案: 我能想到的两个原因: 删除表示通用参数在运行时不可用,因此不 知道 它包含字符串,而只是原始类型。因此,所有对的调用都必须返回,这并不是严格正确的。您实际上必须创建第二个数组

  • 问题内容: 我有一个代表文本片段的泛型类。该文本片段可能具有多种不同模式(突出显示的不同类型)中的任何一种。这些模式用枚举表示。每个项目的Enum可能不同,但是它必须实现一个接口,该接口提供了一种将其中两个结合的方法(可以突出显示并加粗显示)。所以我有一个界面: 然后我的TextFragment是文本字符串和模式的容器。但是当我尝试声明该类时: 我收到以下错误: 令牌“扩展”的语法错误,预期 根据

  • 问题内容: 如果在Java中创建泛型类(该类具有泛型类型参数),则可以使用泛型方法(该方法带有泛型类型参数)吗? 考虑以下示例: 正如您对通用方法所期望的那样,我可以使用任何对象调用的实例: 但是,如果我尝试使用 不 指定泛型类型的实例,则无论传入什么,我都会调用返回, 奇怪的是,如果返回类型是通用类,它将编译(例如(实际上,这可以解释-参见下面的答案)): 此外,如果输入通用类,即使仅使用通配符

  • 如果在Java中创建泛型类(该类具有泛型类型参数),是否可以使用泛型方法(该方法采用泛型类型参数)? 考虑下面的例子: 正如您所期望的那样,对于任何对象,的实例,我都可以调用: 但是,如果我试图使用的实例而不指定泛型类型,那么调用将返回一个

  • 我知道你用 假设有动物超类和狗猫子类。基本上我想要一个包含狗和猫的列表。我发现我可以做到以下几点: 上面的代码可以编译。那么,它是否违反了我为动物主义者写价值观的规则?

  • 本文向大家介绍Java中的泛型详解,包括了Java中的泛型详解的使用技巧和注意事项,需要的朋友参考一下 所谓泛型:就是允许在定义类、接口指定类型形参,这个类型形参在将在声明变量、创建对象时确定(即传入实际的类型参数,也可称为类型实参) 泛型类或接口 “菱形”语法 从泛型类派生子类 伪泛型 不存在真正的泛型类,泛型类对Java虚拟机来说是透明的.JVM并不知道泛型类的存在,换句话来说,JVM处理泛型