在范围内没有封闭类型的实例

时间:2014-03-01 16:34:43

标签: java inheritance instantiation inner-classes

我调查java内部类。

我写了一个例子:

public class Outer {
    public Outer(int a){}

    public class Inner {
        public Inner(String str, Boolean b){}
    }

    public static class Nested extends Inner{
        public static void m(){
            System.out.println("hello");
        }
        public Nested(String str, Boolean b , Number nm)   { super("2",true);   }
    }

    public class InnerTest extends Nested{
        public InnerTest(){  super("str",true,12);  }
    }
}

我使用以下字符串从main调用它:

 new Outer(1).new Inner("",true);

我看到编译错误:

  java: no enclosing instance of type testInheritancefromInner.Outer is in scope

你能解释一下这种情况吗?

更新

enter image description here

2 个答案:

答案 0 :(得分:15)

正如Sotirios所说,你的嵌套(非内部)类没有隐式地有一个Outer的实例来有效地提供给Inner

可以绕过这个,但明确地.super部分之前指定它:

public Nested(String str, Boolean b, Number nm) { 
    new Outer(10).super("2", true);
}

甚至接受它作为参数:

public Nested(Outer outer) { 
    outer.super("2", true);
}

但是,我强烈建议您避免使用这种错综复杂的代码。我大部分时间都避免使用嵌套类,几乎总是命名内部类,我不记得使用它们的组合

答案 1 :(得分:14)

Inner是一个内部类。只有在包含Inner类定义的类的封闭实例时才能创建它。

但是,您已经创建了一个static嵌套类Nested,该类从此类扩展而来。当您尝试调用超级构造函数

public Nested(String str, Boolean b , Number nm)   { super("2",true);   }

它会失败,因为Inner的超级构造函数依赖于Outer的实例,static类的Nested上下文中不存在。 Jon Skeet provides a solution.

解决方案的解释显示在JLS here

  

超类构造函数调用可以细分:

     
      
  • 不合格的超类构造函数调用以关键字开头   super(可能以显式类型参数开头)。

  •   
  • 合格的超类构造函数调用以Primary开头   表达

         
        
    • 它们允许子类构造函数显式指定新的   创建的对象立即封闭了相对于的实例   直接超类(第8.1.3节)。当超类时,这可能是必要的   是一个内在的阶层。
    •   
  •