静态嵌套类作为泛型类型绑定不起作用

时间:2013-07-05 21:34:39

标签: java generics intellij-idea

文件 AbstractContainer.java

package container;

import static container.AbstractContainer.*;

public abstract class AbstractContainer<ElementType extends AbstractElement> {
    public static abstract class AbstractElement {
    }
}

文件 ConcreteElement.java

package container;

import static container.ConcreteContainer.*;
import static container.AbstractContainer.*;

public class ConcreteContainer extends AbstractContainer<ConcreteElement> {
    public static class ConcreteElement extends AbstractElement {
    }
}

这段代码给了我一个编译错误:

java: type argument container.ConcreteContainer.ConcreteElement is not within bounds of type-variable ElementType

但是IDE没有看到任何问题(IDEA 12)。

第一:这里发生了什么?

第二个问题,在 AbstractContainer.java 中,为什么我必须静态导入嵌套类(显然在范围内),以便在泛型类型(extends AbstractElement而不是{{}中使用它1}})?

2 个答案:

答案 0 :(得分:1)

首先,您不必静态导入该类。只需限定对内部类的引用:

public abstract class AbstractContainer<ElementType extends 
    AbstractContainer.AbstractElement> {

public class ConcreteContainer extends 
    AbstractContainer<ConcreteContainer.ConcreteElement>

使用Java 1.6进行编译时,我看不到编译器错误。但是我在用1.7编译时确实看到了它。

实际上,在声明AbstractElement时,完全符合条件ConcreteElement似乎满足了编译器:

public class ConcreteContainer extends 
    AbstractContainer<ConcreteContainer.ConcreteElement> {
                                           // fully qualify here
    public static class ConcreteElement extends AbstractContainer.AbstractElement {
    }
}

答案 1 :(得分:1)

第一个问题 - 可能是编译器错误。

第二个问题 - 可能是由于技术性问题:

http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.3

  

在类C(第8.1.6节)中声明或继承的成员m的声明范围是C的整个主体

例如

@SomeAnnotation(M.class)
class C
<T extends M>
{
    static class M{}
}

代码是非法的,因为MC的正文之外,注释和类型参数中使用。

在Java 5之前,没有注释/泛型,因此“C的整个主体”涵盖所有地方“M”可以合理引用。但现在规则已经过时,我们应该真正扩大M的范围;我没有看到这样做有任何问题。