Java泛型错误[重复]
Posted
技术标签:
【中文标题】Java泛型错误[重复]【英文标题】:Java Generics Error [duplicate] 【发布时间】:2012-05-11 00:35:13 【问题描述】:可能重复:Java how to: Generic Array creationError: Generic Array Creation
我收到此错误:
Cannot create a generic array of T
这是我的代码(第 6 行错误):
1 public class HashTable<T>
2
3 private T[] array;
4
5 HashTable(int initSize)
6 this.array = new T[initSize];
7
8
我想知道为什么会出现这个错误以及修复它的最佳解决方案。谢谢。
更新:
我调整了我的代码,以便数组改为采用链表,但我收到了一个新错误。
这是我的错误:
Cannot create a generic array of LinkedList<T>
这是我的代码(第六行错误):
1 public class HashTable<T>
2
3 private LinkedList<T>[] array;
4
5 HashTable(int initSize)
6 this.array = new LinkedList<T>[initSize];
7
8
此错误是否出于完全相同的原因?我只是假设我可以创建通用链表并将它们存储在数组中。
【问题讨论】:
这可能是不可能的:***.com/a/217110(认为这不太一样) ***.com/questions/529085/… 这是因为类型擦除,见:docs.oracle.com/javase/tutorial/java/generics/erasure.html 你不想要一个链表数组——你只需要一个链表(或 ArrayList)并将其视为一个数组!即与 AlexR 的回答完全相同。 ArrayList 是数组周围的简单 Collection 包装器。 我实际上是在实现一个哈希表(对于某个实现)需要数组来保存数组列表。我发现简单的转换方法最适合我的场景。 (LinkedList是的,不能创建泛型数组。 我知道的最好的解决方法是使用集合:
private List<T> list;
.......
list = new ArrayList<T>();
【讨论】:
这不正确,如我的回答中所示,通用数组可以被创建。 并非没有(ewwwwww)反射。【参考方案2】:泛型数组可以通过反射创建(尽管需要不安全的强制转换),您只需要将类作为参数传递(假设以下方法在定义@的类内部987654321@类型参数):
@SuppressWarnings("unchecked")
public T[] createArray(Class<T> klass, int size)
return (T[]) Array.newInstance(klass, size);
例如,在您的情况下:
HashTable<Integer> t = new HashTable<Integer>();
Integer[] intArray = t.createArray(Integer.class, 4);
intArray[0] = 1; intArray[1] = 2;
intArray[2] = 3; intArray[3] = 4;
System.out.println(Arrays.toString(intArray));
> [1, 2, 3, 4]
【讨论】:
这是一个反射创建的数组,不安全地转换为泛型类型。不确定它是否会算作通用数组创建。至少它不适合我。对我来说,关键是在运行时没有完整的泛型类型信息,因此不可能实例化一个新的 T。 虽然这个解决方案需要强制转换和警告抑制,但它显示了一个很好的解决方法。我认为这里的所有人都给出了有用的答案。(T[])Array.newInstance()
就像 (T[])new Object[]
和 (T[])new ArrayList<T>().toArray()
。 @Amir Pashazadeh 完美解释了所有这些解决方案“不清楚”
@edalorzo 你是对的,我在答案的开头添加了一个警告
@Alex (T[]) new Object[]
会不会最终导致ClassCastException
?因为数组是可具体化的,而Object
的数组不是T
的数组,因此据我所知,这个演员永远不会成功。如果是这样,这不能与建议的答案相同。由于同样的原因,两者都不会成功 toArray()
方法。【参考方案3】:
您不能创建 T(在 Java 中),但 T[] 在内部与 对象[]。
public class HashTable<T>
private T[] array;
@SuppressWarnings("unchecked")
HashTable(int initSize)
this.array = (T[]) new Object[initSize];
(会编译,我检查过)
由于 newacct 的 cmets,最好只使用 Object[] 并将项目转换为 T。
public class HashTable<T>
private Object[] array;
public HashTable(int initSize)
this.array = new Object[initSize];
public void put(String pKey, T pItem)
...
array[x] = pItem;
....
public T get(String pKey)
...
return (T) array[x];
【讨论】:
是的,但是您必须小心,因为如果您有一个方法将该数组作为T[]
返回到外部,它将崩溃并且不会有任何警告。例如public T[] toArray() return array;
@newacct:我查过了,你是对的。然而,它仍然让我感到疑惑。构造函数中的强制转换不会引发异常。将任何类型放入 Object[] 中是合法的。在这种情况下,我认为不需要抛出异常
不同的数组类型在运行时是不同的类,所以如果你创建一个Object[]
,你不能将它转换成String[]
。构造函数中没有真正的强制转换,因为T
在类的范围内被删除。相反,每次有人从T
类型的类中得到一些东西时,编译器都会在那里插入一个他们期望的类型的转换。例如当有人调用HashTable<String> foo = ...; String bar = foo.get("baz");
时被擦除为HashTable foo = ...; String bar = (String)foo.get("baz");
这就是调用代码中发生异常的原因。以上是关于Java泛型错误[重复]的主要内容,如果未能解决你的问题,请参考以下文章