我有这段代码
public class OuterClass<T> {
public OuterClass() {
InnerClass[] array = new InnerClass[4]; // compile-error
}
private class InnerClass {
}
}
由于无法在我创建数组的行中创建OuterClass.InnerClass 的通用数组而无法编译。
为什么会这样,我该如何修复/解决它?
答案 0 :(得分:3)
InnerClass
是一个非静态的内部类。 OuterClass
的非静态成员属于T
的类型参数OuterClass
的范围。这意味着 InnerClass
隐式通用。
每次在OuterClass
的实例上下文中,只编写InnerClass
,而没有明确限定它,它会被隐含地视为OuterClass<T>.InnerClass
。所以当你写了
InnerClass[] array = new InnerClass[4];
编译器将其视为
OuterClass<T>.InnerClass[] array = new OuterClass<T>.InnerClass[4];
// ^
// see? you are using "new" to create an array of a parameterized type
即使参数实际上不在InnerClass
上,它也在OuterClass
上,它仍然是InnerClass
的类型参数,只是写在不同的位置。
如您所知,在Java中不允许创建参数化类型的数组。就像不允许使用List<T>[] = new List<T>[4];
一样。
那么创建泛型类型数组的常用解决方法是什么?您可以创建原始类型的数组:
List<T>[] = new List[4]; // legal
或通配符参数化类型:
List<T>[] = (List<T>[])new List<?>[4]; // legal
现在回到你的内部课的问题。这种情况下的原始类型是什么?它不是InnerClass
,因为正如我们所看到的,它是用T
隐式参数化的。我们必须使用原始InnerClass
明确限定 OuterClass
以获取原始InnerClass
:
InnerClass[] = new OuterClass.InnerClass[4]; // legal
或者使用通配符参数化类型(同样,我们必须将通配符放在OuterClass
上):
InnerClass[] = (InnerClass[])new OuterClass<?>.InnerClass[4]; // legal
答案 1 :(得分:1)
解决方法:创建内部类static
public class OuterClass<T> {
public OuterClass() {
InnerClass[] array = new InnerClass[4];
}
private static class InnerClass {
}
}
答案 2 :(得分:-2)
因此,您需要对InnerClass进行参数化,因为它不知道正在处理什么。把课程从外层阶级中解脱出来。
但是,你对内部类的修复就是这样。
package quicktest;
public class OJust<T>{
public OJust() {
InnerClass[] array = new InnerClass[4]; // compile-error
}
private class InnerClass<T>{
}
}