【问题标题】:How does Array.newInstance() work?Array.newInstance() 是如何工作的?
【发布时间】:2015-03-12 15:17:44
【问题描述】:

我目前正在研究 Java 集合框架,我一直在问自己一个有趣的问题是“所有这些集合如何实现 Collection#toArray 方法的通用版本”。从我在其他 SO 问题中读到的内容来看,它很可能使用Array#newInstance。仅供参考,这就是 Array#newInstance 的声明方式:

public static Object newInstance(Class<?> componentType,
                     int... dimensions)
                     throws IllegalArgumentException,
                            NegativeArraySizeException

现在,我的问题是:如何使提供给该方法的信息足以生成指定类型的数组对象

多维方面并不难,因为总是可以将 N-dim 数组构造为 (N-1)-dim 数组的单维数组。 真正困扰我的是如何从通过Class&lt;?&gt; 引用传递的Class&lt;T&gt; 对象创建T[] 类型的对象。

【问题讨论】:

  • 在 Oracle JDK 中,newInstance 委托给实际返回新数组的 privatenative 方法。实际的创建是由 JVM 动态完成的。
  • @SotiriosDelimanolis,那么,这种方法实际上是唯一创建类型在运行时提供的数组的方法吗?没有办法使用 Java 本身提供的工具来实现同样的目标?
  • 你不能这样做——泛型在运行时不存在。如果再次查看 Collections 的 API,您可以看到 toArray 的空参数版本返回一个 Object[]。要获取参数化/类型化数组,您必须先创建该数组并将其传递给方法。
  • 这是 Java 提供的工具。而且,是的,这是唯一的方法(减去一些Serializable,但忽略它)。

标签: java arrays generics


【解决方案1】:

如果您考虑一下,在反射 API 中拥有这样的功能是有意义的。当您执行new SomeType[N] 时,编译器基本上会编译成字节码,即创建一个新数组,组件类型为SomeType,长度为N

因此 JVM 必须在运行时已经有某种机制来评估此类指令,给定给定的组件类型和长度,分配一个新数组。 new SomeType[N] 的唯一问题是组件类型在编译时是硬编码的。但是如果类型是在运行时给出的,对 JVM 来说不会更困难,因为 JVM 有一个运行时机制来获取类型。由于没有允许您创建具有动态类型的数组的本机语法,因此反射 API 提供了一种方法来执行此操作。

【讨论】:

  • 感谢您的意见。虽然我的主要问题是关于是否有可能通过不依赖任何本机方法来实现Array.newInstance 提供的相同功能。显然@SotiriosDelimanolis 已经在他的 cmets 中给出了答案。
【解决方案2】:

拥有这个能力在逻辑上是正确的,jdk通过Array.newInstance方法提供这个。但是实现是在 jvm 内部的,所以你无法知道它们是如何在非开源 jvm 中实现的。我建议你检查一下 openJVM 源代码,因为它们提供了类似的功能。

【讨论】:

    猜你喜欢
    • 2013-07-18
    • 2017-07-24
    • 2016-11-13
    • 2017-10-11
    • 2021-10-13
    • 2011-02-24
    • 2013-11-16
    • 2011-10-16
    • 2012-11-03
    相关资源
    最近更新 更多