4

文件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而不是extends AbstractContainer.AbstractElement)中使用它?

4

2 回答 2

1

First question - probably a compiler bug.

Second question - probably due to technicality:

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

The scope of a declaration of a member m declared in or inherited by a class type C (§8.1.6) is the entire body of C

For example

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

the code is illegal, because M is used outside the body of C, in annotation, and in type parameter.

Prior to Java 5, there's no annotation/generics, therefore "the entire body of C" covers all places "M" can be sensibly referenced. But now the rule is outdated, we should really extend the scope of M a little bit; I don't see any problem in doing that.

于 2013-07-05T23:35:58.387 回答
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 {
    }
}
于 2013-07-05T21:43:02.490 回答