2017-08-09 41 views
3

我的理解下面的代码应该运行没有任何编译错误。编译失败,通用类与通用接口

但是,当我运行这个程序时,我收到以下编译错误。

The member type B.D cannot be qualified with a parameterized type, since it is static. Remove arguments from qualifying type 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]; 
} 

请帮助我理解这种行为。

+0

为了记录:我从您的示例中删除了第一个A类 - 因为该类不会导致整体问题。所以我觉得它很混乱。 – GhostCat

+0

@ GhostCat-谢谢。 –

回答

4

以类似于内部static类的方式,嵌套接口不与其外部类的实例关联,而仅与类本身有关联。无论B的类型参数如何,所有static成员在B的所有实例中共享。试想一下:

class B<T> { 
    public static int shared = 0; 
} 

变量sharedB<String>B<Integer>B<Object>等相同。访问它的一个参数B的尝试导致编译错误:

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

因此,中B类型参数对的arr的声明没有任何影响,所以Java希望你删除它:

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

@GhostCat我没有研究*你的编辑,我记得大部分*我的编辑都是这样的。此外,格式化,我经常为了能够自己阅读问题而做的;-) – dasblinkenlight

+0

除此之外:看到你7到10周......传说中的下一个;-) – GhostCat

1

内部接口始终是static(与类不同)。因此B的参数String在定义new B<String>.D<String>中没有意义。

2

首先,你可以用而不是创建具体参数化类型的数组。例如:

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

不起作用。详情请参阅here

但它看起来像编译器在这里给你,因为它第一绊倒在事实嵌套接口类似于静态内部类不同,少有用的错误消息。

所以,你唯一可以做的事情是:忽略的赋值的RHS泛型类型:

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

这当然会导致类型安全警告 - 并使得整体构思该内部接口通用性已经过时了。

所以真正的答案可能是:泛型和数组在Java中不能很好地结合在一起 - 首先避免使用它们。通过引入界面嵌套结果的“更好的用户体验”,使得事物更加复杂不要感到惊讶。