以下代码给出了“通用数组创建”错误。
public class TestClass<K, V> {
Entry[] entry;
private TestClass() {
entry = new Entry[10]; // <--- this line gives generic array creation error
}
private class Entry {
public Entry() {
}
}
}
我想知道为什么会这样,因为类Entry
不是泛型类,并且没有泛型类型的对象。
是因为内部类仍然可以访问泛型类型,即使它不使用任何类型?这是我能想到的最好的,但如果是这样的话,我不明白为什么Java看起来不会看到它不使用泛型类型,因此不是通用类?
是的,我看过很多关于泛型类型数组的线程,但是没有,我没有找到一个关于内部类的线程。
答案 0 :(得分:6)
该类型实际上是TestClass<K, V>.Entry
(是的,因为它是一个内部类)。您可以通过将其转换为嵌套的静态类来解决此问题:
private static class Entry {
public Entry() {
}
}
答案 1 :(得分:5)
这是关于JLS谈论数组创建表达式的内容:
ArrayCreationExpression:
[...]
new ClassOrInterfaceType DimExprs [Dims]
[...]
如果
ClassOrInterfaceType
未表示,则为编译时错误 可再生类型(§4.7)。否则,ClassOrInterfaceType
可能会命名 任何命名的引用类型,甚至是抽象类类型(第8.1.1.1节)或 界面类型。
当且仅当下列之一成立时,类型才可以恢复:
它指的是非泛型类或接口类型声明。
它是一个参数化类型,其中所有类型参数都是无界的 通配符(§4.5.1)。
这是一种原始类型(§4.8)。
这是一种原始类型(§4.2)。
这是一个数组类型(第10.1节),其元素类型是可以恢复的。
答案 2 :(得分:1)
UnderflowException
是一个非静态的内部类。这意味着它属于外部类的泛型参数的范围。每次你在Entry
内写一个不合格的Entry
时,它隐含地意味着TestClass
,这是一个参数化类型!如您所知,您无法创建参数化类型的数组,例如你做不到TestClass<K,V>.Entry
。
通常,创建参数化类型数组的解决方法是创建一个原始类型的数组,即new ArrayList<String>[5]
,或通配符参数化类型的数组,即new ArrayList[5]
。但在这种情况下,什么是原始类型?答案是您必须使用原始外部类类型明确限定new ArrayList<?>[5]
:
Entry
或者使用通配符参数化类型:
entry = new TestClass.Entry[10];