假设您有一个如下定义的arraylist:
ArrayList<String> someData = new ArrayList<>();
在稍后的代码中,由于泛型,您可以这样说:
String someLine = someData.get(0);
编译器直接知道它将得到一个字符串。耶,泛型!但是,这将失败:
String[] arrayOfData = someData.toArray();
toArray()
将始终返回一个对象数组,而不是所定义的泛型对象。为什么get(x)
方法知道它返回的是什么,而toArray()
缺省为对象?
发布于 2016-04-13 20:53:47
通用信息在运行时是erased。JVM不知道您的列表是List<String>
还是List<Integer>
(在运行时,List<T>
中的T
被解析为Object
),因此惟一可能的数组类型是Object[]
。
您可以使用toArray(T[] array)
-在这种情况下,JVM可以使用给定数组的类,您可以在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());
发布于 2016-04-13 20:54:55
如果查看Javadoc for the List
interface,您会注意到toArray
的第二种形式:<T> T[] toArray(T[] a)
。
事实上,Javadoc甚至给出了一个示例,说明如何准确地完成您想要做的事情:
String[] y = x.toArray(new String[0]);
发布于 2016-04-14 02:36:47
需要注意的是,Java中的数组在运行时知道它们的组件类型。String[]
和Integer[]
在运行时是不同的类,您可以在运行时向数组询问它们的组件类型。因此,需要在运行时使用组件类型(通过在编译时使用new String[...]
对可重用的组件类型进行硬编码,或者使用Array.newInstance()
并传递类对象)来创建数组。
另一方面,泛型中的类型参数在运行时不存在。在运行时,ArrayList<String>
和ArrayList<Integer>
之间完全没有区别。这一切都只是ArrayList
而已。
这就是为什么您不能只获取List<String>
并获取String[]
而不以某种方式单独传入组件类型的根本原因--您必须从没有组件类型信息的对象中获取组件类型信息。显然,这是不可能的。
https://stackoverflow.com/questions/36598928
复制相似问题