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

gst*_*low 8 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);  }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

 new Outer(1).new Inner("",true);
Run Code Online (Sandbox Code Playgroud)

我看到编译错误:

  java: no enclosing instance of type testInheritancefromInner.Outer is in scope
Run Code Online (Sandbox Code Playgroud)

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

UPDATE

在此输入图像描述

Jon*_*eet 16

正如Sotirios所说,你的嵌套(非内部)类并不隐含有一个Outer有效提供的实例Inner.

但是,您可以通过在部件之前明确指定它来解决此问题.super:

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

甚至接受它作为参数:

public Nested(Outer outer) { 
    outer.super("2", true);
}
Run Code Online (Sandbox Code Playgroud)

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

  • 记住我在实际代码中从未见过的语法的+1(并且不想):-) (2认同)

Sot*_*lis 15

Inner是一个内在阶级.它只能在包含Inner类定义的类的封闭实例时创建.

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

public Nested(String str, Boolean b , Number nm)   { super("2",true);   }
Run Code Online (Sandbox Code Playgroud)

它会失败,因为超级构造函数Inner依赖于类Outerstatic上下文中不存在的实例Nested.Jon Skeet提供了一个解决方案.

解决方案的解释在此处出现在JLS中.

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

  • 非限定超类构造函数调用以关键字super开头(可能以显式类型参数开头).

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

    • 它们允许子类构造函数显式指定新创建的对象关于直接超类(第8.1.3节)的直接封闭实例.当超类是内部类时,这可能是必要的.