【问题标题】:no enclosing instance of type... in scope范围内没有类型...的封闭实例
【发布时间】:2014-04-02 17:57:55
【问题描述】:

我研究 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

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

更新

【问题讨论】:

标签: java inheritance instantiation inner-classes


【解决方案1】:

正如 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);
}

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

【讨论】:

  • outer.super() 等构造函数中使用的外部类实例的引用不仅可以是参数,还可以是字段。这样你就可以悄悄地扩展一个在其外部类之外的内部类。
【解决方案2】:

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

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

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

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

解决方案的解释出现在 JLS here

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

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

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

    • 它们允许子类构造函数显式指定新的 相对于 直接超类(§8.1.3)。当超类时,这可能是必要的 是一个内部类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多