首先让我们说我有一个LinkedList<String>
,
我可以通过toArray()
轻松将其转换为数组。即。
LinkedList<String> strList = new LinkedList<String>();
String[] strArray = strList.toArray(new String[0]);
但是我们说我有LinkedList<T>
然后我下面的代码:
LinkedList<T> tList = new LinkedList<T>();
T[] strArray = tList.toArray(new T[0]);
我得到无法创建T 的通用数组错误消息。
我该如何解决这个问题?
特别是在我的班级中我有LinkedList<AbstractNode<T>> nodes
,我正在尝试实现一个getAll()方法,该方法将所有节点作为数组返回。
谢谢!
注意PéterTörök的答案为我的问题提供了正确的答案,但对于我来说,简单地返回一个ArrayList而不是像Bar所提到的那样,最终平滑了我的代码。
Note2 在看了我的代码后,我甚至不确定是否需要进行任何转换,LinkedList对于我试图做的事情很好......: - /
答案 0 :(得分:13)
类库中使用的解决方法是(使用未经检查的强制转换)
public <T> T[] toArray(List<T> list, T[] a) {
if (a.length < list.size()) {
a = (T[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(), list.size()));
}
return list.toArray(a);
}
或者,使用Class
参数而不是数组:
public <T> T[] toArray(List<T> list, Class<T> k) {
return list.toArray(
(T[])java.lang.reflect.Array.newInstance(k, list.size()));
}
来自Java Generics and Collections,第6.4-5章。
无法创建通用数组是Java中最严重的限制之一。因为它太烦人了,所以值得重申它发生的原因:通用数组是有问题的,因为泛型是通过擦除来实现的,但是擦除是有益的,因为它可以简化进化。
最佳解决方法是优先使用集合框架中的
ArrayList
或其他类,而不是数组。我们在2.5节讨论了集合类和数组之间的权衡,并且我们注意到在许多情况下集合比数组更可取:因为它们在编译时捕获更多错误,因为它们提供了更多操作,并且因为它们在表示方面提供了更大的灵活性。到目前为止,数组提供的问题的最佳解决方案是“只说不”:使用集合优先于数组。有时这不起作用,因为出于兼容性或效率的原因需要一个数组。集合框架中出现了这种情况:为了兼容性,方法toArray将集合转换为数组[...]
[...]将一个集合转换为一个数组的天真方法是行不通的。我们可能尝试的第一个修复是添加一个未经检查的强制转换,但我们很快就会看到这会导致更复杂的问题。正确的解决方案需要我们求助于反思。
答案 1 :(得分:1)
由于Java generic实际上是用类型object
替换你的T并转换为在编译时解析的具体类型,因此可以创建List<T>
,但不能创建T[]
。 (第一个是对象列表,第二个是未知的)
好反射可以让你做很多丑陋的黑客攻击。你可以使用它们。我个人只有在没有其他方法可以做的时候才使用它们。我不喜欢运行时错误。
但我的问题是:您真的需要T[]
,为什么不使用ArrayList<T>
?