Java Generics Error
Possible Duplicate:
Java how to: Generic Array creation
Error: Generic Array Creation
我得到这个错误:
1
| Cannot create a generic array of T |
这是我的代码(第6行出错):
1 2 3 4 5 6 7 8
| 1 public class HashTable<T> {
2
3 private T[] array;
4
5 HashTable(int initSize) {
6 this.array = new T[initSize];
7 }
8 } |
我想知道为什么会出现这个错误,以及修复它的最佳解决方案。谢谢。
更新:
我调整了我的代码,使数组接受链表,但我得到了一个新的错误。
这是我的错误:
1
| Cannot create a generic array of LinkedList<T> |
这是我的代码(第六行出错):
1 2 3 4 5 6 7 8
| 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 } |
这个错误是因为完全相同的原因吗?我只是假设我可以创建通用的链接列表并将它们存储在数组中。
- 这可能是不可能的:stackoverflow.com/a/217110(认为这不是完全相同的事情)
- stackoverflow.com/questions/529085/&hellip;
- 这是因为类型擦除,请参见:docs.oracle.com/javase/tutorial/java/generics/eraure.html
- 您不需要一个链表数组-您只需要一个链表(或array list)并将其视为一个数组!也就是说,完全按照亚历克瑟的回答。arraylist是围绕数组的简单集合包装器。
- 实际上,我正在实现一个哈希表(对于特定的实现),需要数组保存数组列表。我发现简单的铸造方法最适合我的场景。(linkedlist[](new linkedlist[initsize])
是的,无法创建泛型数组。我所知道的最佳解决方法是使用集合:
1 2 3 4 5
| private List<T> list;
.......
list = new ArrayList<T>(); |
- 这是不正确的,如我的答案所示,可以创建通用数组。
- 没有(ewwwwww)反射。
可以通过反射创建泛型数组(尽管需要不安全的强制转换),但只需将类作为参数传递(假定以下方法位于定义类型参数的类中):
1 2 3 4
| @SuppressWarnings ("unchecked")
public T [] createArray (Class <T > klass, int size ) {
return (T []) Array. newInstance(klass, size );
} |
例如,在您的案例中:
1 2 3 4 5 6 7
| 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().toArray()相似。所有这些解决方案都"不清楚",这是@amir pashazadeh完美解释的。
- @伊达洛佐,你说得对,我在回答的开头加了个警告。
- @亚历克斯会不会最终导致一个ClassCastException?因为数组是不可重设的,而一个Object数组不是T数组,因此据我所知,这种转换永远不会成功。如果是这样,这就不能与建议的答案相同。由于同样的原因,这两种方法都不可能取代toArray()方法。
你不能创建一个T(在Java中),但是t[]内部是一样的对象[]。
1 2 3 4 5 6 7 8 9
| public class HashTable <T > {
private T [] array ;
@SuppressWarnings ("unchecked")
HashTable (int initSize ) {
this. array = (T []) new Object[initSize ];
}
} |
(将编译,我检查过)
由于newacct的注释,只使用对象[]并将项强制转换为t可能会更好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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; }。
- @我查过了,你说得对。不过,我还是很好奇。强制转换构造函数不会引发异常。把任何类型的东西放进一个物体中是合法的。我不认为有必要在这种情况下抛出异常
- 不同的数组类型在运行时是不同的类,因此如果创建一个Object[],就不能将其强制转换为String[]。构造函数中没有真正的强制转换,因为T在类的范围内被擦除。相反,每当有人从T类型的类中获得某些内容时,编译器将在该类中插入他们期望的类型的强制转换。例如,当有人调用HashTable foo = ...; String bar = foo.get("baz");时,该异常会被删除到HashTable foo = ...; String bar = (String)foo.get("baz");,这就是调用代码中出现异常的原因。