[英]Cannot create a generic array
我收到以下代码的错误“无法创建通用数组”:
public class MapImpl<K, V> {
private static int DEFAULT_CAPACITY = 16;
private int size;
// array holding the entries of the map
private Entry[] entries;
public MapImpl() {
entries = new Entry[DEFAULT_CAPACITY]; // error at this line: Cannot create a generic array of MapImpl<K,V>.Entry
}
// represents an entry in the map
private class Entry {
private K key;
private V value;
public Entry(K key, V value) {
this.key = key;
this.value = value;
}
}
令人惊讶的是,这很好用:
public class MapImpl<K, V> {
private static int DEFAULT_CAPACITY = 16;
private int size;
// array holding the entries of the map
private Entry<K, V>[] entries;
public MapImpl() {
entries = new Entry[DEFAULT_CAPACITY];
}
// represents an entry in the map
private class Entry<K, V> {
private K key;
private V value;
//but here K and V are being hidden.
public Entry(K key, V value) {
this.key = key;
this.value = value;
}
}
}
我确实知道我们无法创建泛型类型或采用类型参数的类型的数组。 但是,在我的代码中,Entry类不是通用类型。 我在俯视什么吗?
这里的问题是非静态嵌套类可以访问其外部类的所有成员,其中包括有关外部类中使用的泛型类型的信息,例如
class Outer<T>{
private T t;
class Inner{
void method(T tt){//we can use same type T as used in outer class
t = tt;
}
}
}
所以实际上Inner
类的类型更像是Outer<T>.Inner
使得它的形式为泛型类型,并且由于类型擦除会导致无法从泛型类型创建数组,这会阻止数组测试添加的元素是否有效。
在这种情况下,最常见的解决方案是使用集合而不是诸如List<OurType>
类的数组。
但是,如果您真的只想拥有数组,那么其他可能的解决方案(但应避免使用它)是使用原始类型,因此,
new Entry[DEFAULT_CAPACITY];
相当于
new MapImpl<K, V>.Entry[DEFAULT_CAPACITY];
你可以用
new MapImpl.Entry[DEFAULT_CAPACITY];
// ^no generic type -> it is raw type
解决方案
private class Entry<K, V> {
private K key;
private V value;
//but here K and V are being hidden.
public Entry(K key, V value) {
this.key = key;
this.value = value;
}
}
可能有效 (我找不到描述此内容的任何相关JLS),因为正如您所说,您已经屏蔽了外部类的原始K
和V
,这意味着您现在无法访问它们
void method(T tt){
t = tt;
}
方法不能编译,因为T
从内部类不一样T
从外部类。 因此, Entry
不再是MapImpl<K,V>.Entry
而是MapImpl.Entry<K,V>
,当您将其编写为
new Entry[...]
您明确地将其设为可以使用的原始类型(在声明private Entry[] entries
时出现有关原始类型的编译警告)
将Entry
类声明为静态。 当前它不是静态的,因此它隐式链接到MapImpl实例及其通用参数。
编辑:我的意思是
private static class Entry<K, V>
由于Entry
是通用类MapImpl
的内部类,因此它也由K
和V
参数化。 要创建一个数组,必须使用原始类型创建它:
entries = new MapImpl.Entry[DEFAULT_CAPACITY];
这是因为Java的数组(与泛型不同)在运行时包含有关其组件类型的信息。 因此,在创建数组时必须知道组件类型。 由于您在运行时不知道K
和V
是什么,因此无法创建数组。
请尝试以下代码
package com.vibhs.stack.overflow.generics;
public class MapImpl<K, V> {
private static int DEFAULT_CAPACITY = 16;
private int size;
// array holding the entries of the map
private Entry[] entries;
public MapImpl() {
entries = new Entry[DEFAULT_CAPACITY]; // error at this line: Cannot
// create a generic array of
// MapImpl<K,V>.Entry
}
// represents an entry in the map
private class Entry<K,V> {
private K key;
private V value;
public Entry(K key, V value) {
this.key = key;
this.value = value;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.