编译泛型接口的泛型类失败

3
据我理解,以下代码应该可以无错误编译运行。
然而,在我运行这个程序时,出现了以下编译错误:
“成员类型B.D不能用参数化类型来限定,因为它是静态的。从限定类型B中删除参数。”
class B<X> {
    interface C {
    }

    interface D<Y> {
    }
}

class Test {
     // compilation fails here
    B<String>.D<String>[] arr = new B<String>.D<String>[10];
}

请帮我理解这种行为。

记录一下:我从你的例子中删除了第一个A类 - 因为那个类对整个问题没有贡献。所以我觉得它会让人感到困惑。 - GhostCat
@GhostCat- 谢谢。 - T-Bag
3个回答

4
与内部静态类类似,嵌套接口(Nested Interface)没有与外部类的实例相关联,仅与类本身相关联。所有静态成员在所有 B 实例之间共享,不考虑 B 的类型参数。例如:
class B<T> {
    public static int shared = 0;
}

B<String>B<Integer>B<Object>等中的变量shared是相同的。在参数化的B上尝试访问它会导致编译错误:

int copy = B<String>.shared; // <<== Does not compile

因此,B 的类型参数对 arr 的声明没有影响,因此 Java 希望您将其删除:
B.D<String>[] arr = new B.D[10];

@GhostCat 我没有研究过你的编辑,我记得大部分我的编辑都是这样的。当然,还有格式,我经常这样做是为了能够自己阅读问题;-) - Sergey Kalinichenko
除此之外:我们7到10周后见...下一个传奇即将诞生;-) - GhostCat

2

首先,您不能创建具体参数化类型的数组。例如:

Pair<Integer,Integer>[] intPairArr = new Pair<Integer,Integer>[10]; // illegal 

不起作用。有关详细信息,请参见此处

但是,看起来编译器在此处给出了不同的、不那么有帮助的错误消息,因为它首先遇到了嵌套接口类似于静态内部类的事实。

因此,你唯一能做的就是:在赋值语句的右侧忽略泛型类型:

B.D<String>[] arr = new B.D[10];

当然,这会导致类型安全警告 - 这使得内部接口的泛型概念有些过时。
因此,真正的答案可能是:在Java中,泛型和数组并不兼容 - 首先避免使用它们。而且,当引入接口嵌套使事情变得更加复杂时,不要感到惊讶,因为这会导致用户体验更差。

1

内部接口始终是静态的(与类不同)。 因此,在定义 new B&lt;String>.D&lt;String> 时,参数 String 对B没有意义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接