【问题标题】:Why does java not allow the creation of a generic array? [duplicate]为什么java不允许创建泛型数组? [复制]
【发布时间】:2015-05-27 03:07:02
【问题描述】:

现在,我之前看到过很多与this 或this 类似的问题,我知道答案是“因为擦除”。但我不明白为什么擦除会阻止我们创建泛型数组。

据我所知;数组表示内存的连续分配,包含基元或对对象的引用。除非我弄错了,java 数组只不过是 C/C++ 数组,它们周围有一些花哨的装饰。这是正确的吗?

如果是这样,为什么擦除会阻止像这样为泛型类型创建数组?无论类的类型如何,不是所有引用的大小都相同吗?课程当然会更大或更小,但这不应该影响参考。那么我们不知道数组应该有多大吗?

或者说技术上可行,但是如果我们允许创建泛型数组会遇到其他问题?


明确一点:我了解擦除是什么以及它是如何工作的。 鉴于上述限制,我了解如何创建数组。我不想这样做。

我只是想了解创建数组时需要类型信息的原因。

【问题讨论】:

  • 可以创建一个泛型数组,只有Java编译器不会知道它是一个泛型类型的数组。
  • 为什么:因为“erasure”表示类型被擦除,所以在运行时不可用。
  • 我明白“擦除”是什么意思。我在问为什么类型信息在这种情况下很重要?它提供了什么,我在创建数组时离不开它?
  • java 将组件类型与数组对象相关联。所以String[] 对象与String.class 相关联。为什么?因为协方差。为什么?嗯...我喜欢@raxod502 的说法——“整件事是Java 设计中错误的喜剧”stackoverflow.com/a/2927415/2158288

标签: java arrays generics


【解决方案1】:

你错了。 Java 中的数组具有编码在其中的类型信息。数组本身是一个对象和一个类型。您可以创建一个 String[] 并在其上调用 wait() 和 toString() ,该类型与 String 类型不同。没有一种数组类型,每种类型都是不同的。您可以在 String[] 上调用 getClass(),它会返回与任何其他类型的数组不同的类。

因此,如果它自身的类型被擦除(这就是“擦除”的意思),则没有类型可以创建 T 或其他类型。

所以你必须用Object[] 来伪造它,它可以存储任何类型,但实际上不是特定类型。

但是,您可以反射地创建数组类型。打电话

Array.newInstance( t.getClass(), <dim> );

你可以制作特定类型的数组,只要t是正确的类型。

【讨论】:

  • 我了解擦除部分的含义,甚至了解数组中编码了额外信息的事实(因此“周围有一些花哨的装扮”)。但是,您提到的所有信息(getClass 除外)都与类型无关。那么,除了 getClass(有很多变通方法)之外,数组实际上需要从类型信息中得到什么?
  • 我认为您不了解擦除或“花哨的修饰”。 Java 是一种强类型语言。它不允许您将 String[] 分配给 Integer[] 或反之亦然。它需要类型——被擦除的东西——来制作数组,句号。没有其他真正的方式来表达这一点。
  • 我明白这一点。我也明白 String[] 不同于 Integer[];但我绝不会试图将这些混合在一起。如果我有一个泛型类型 T 和一个类 Foo;编译器不会神奇地让我在它们之间分配。它认为它们是不同的(事实上,大多数静态类型发生在编译时,擦除之前,或者在运行时,在任何这些之后)。 “它需要类型来制作数组,句号”没有回答 为什么 它需要那种类型。它是干什么用的?阻止我将 int 分配到字符串数组中?这是你想说的,还是别的什么?
  • 换一种说法;如果我有T[] things = ...,擦除后看起来像Object[] things = ...。你是想说删除是为了阻止我做(let T = Foo), things[i] = new String()之类的事情吗?
  • 我是说Object[] 与String[] 或Integer[] 不同。如果类型被删除,则不能制作后者。你会做哪个? List&lt;T&gt;T是什么类型,我做哪个数组?
【解决方案2】:

为什么不:

Object [] a = new Object[100];

a 没有做什么,而您期望假设的“通用”数组会做什么?每个元素可以是不同类型的对象。您必须限定对元素的所有访问,但每个元素可以是任何内容,包括 null。

在这个例子中,符号a指的是一个固定大小的对象,并且操作一个数组。唯一“进入”数组的是对其他对象的引用。

【讨论】:

  • 我明白这一点;那不是我要问的。请查看我对我的问题所做的更新;希望这可以澄清它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-05
  • 2010-10-04
  • 2010-11-01
  • 2017-03-03
  • 2016-07-12
相关资源
最近更新 更多