为什么我必须在定义的类中导入嵌套类?

时间:2014-01-14 23:05:30

标签: java compiler-construction

在以下示例中,import是必需的,否则Java的编译器会抱怨Nested无法解析为Iterable<Nested>中的类型:

package test;

import test.Example.Nested;

public class Example implements Iterable<Nested> {

    public final static class Nested {}

}

(使用Iterable<Example.Nested>代替导入工作)

只有在外部类的定义中引用嵌套类时才会发生这种情况,例如:当它用作参数类型时,以及扩展/实现它时(一旦编译器可以解析该类将导致另一个错误),或者在将它用作注释时或在注释中使用时。

我的问题是:为什么编译器在没有显式声明的情况下找不到嵌套类?

3 个答案:

答案 0 :(得分:5)

声明在它出现的范围内是可见的,对于成员来说,该范围是封闭的花括号之间的东西,或者spec放置它:

  

在类类型m(第8.1.6节)中声明或继承的成员C的声明范围是C的整个主体,包括任何嵌套类型声明。

为什么定义这种方式只是Java的创建者能够以任何程度的确定性回答,但我怀疑他们想要尽可能简单的规则,并且说所有成员,变量等都是可见的周围的花括号是一个非常简单的规则。

顺便说一下:您不需要导入类型,您可以使用限定名称。在您的示例中,将显示:

public class Example implements Iterable<Example.Nested> {  }

答案 1 :(得分:1)

嵌套类被引用为<OuterClass>.<InnerClass>,因此Iterable<Example.Nested>将是在Java中执行此操作的典型方法,尽管使用import也是一种选择。

请参阅Java教程中的Nested Classes

答案 2 :(得分:1)

以下代码尚未在类主体“内部”

public class Example implements Iterable<Nested>
{
     // class body starts here

嵌套被引用到课外,所以你必须import或使用Example.Nested来嵌套范围。

如果你在类体中放入类似的代码,它将起作用:

{
      // class body starts here

      public void foo(Iterable<Nested> x) ...
}

这样可以正常工作,因为您现在位于已定义嵌套且可用不合格的类范围内