作用域中没有类型的封闭实例...

16

我研究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);  }
    }
}

我在主函数中使用以下字符串调用它:

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

我看到编译错误:

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

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

更新

enter image description here


请发布完整的代码。 - Antimony
这个 testInheritancefromInner 是什么? - Abimaran Kugathasan
请参见https://dev59.com/D2kw5IYBdhLWcg3w6e0b。 - Raedwald
2个回答

21

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

然而,您创建了一个静态嵌套类Nested,它继承自该类。当您尝试调用超级构造函数时

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

由于Inner的超类构造函数依赖于一个Outer的实例,而这在Nested类的static上下文中不存在,所以它会失败。 Jon Skeet提供了解决方案。

解决方案的解释在JLS中出现这里

  

超类构造函数调用可能分为以下几种:

  
      
  • 未限定的超类构造函数调用以关键字super开头(可能加上显式类型参数)。

  •   
  • 限定的超类构造函数调用以主要表达式开头。

      
        
    • 它们允许子类构造函数明确指定新创建的对象相对于直接超类的立即封闭实例(§8.1.3)。 当超类是内部类时,这可能是必需的。
    •   
  •   

21
如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(),不仅可以是参数,还可以是字段。这样,您就可以在外部类之外轻松扩展内部类。 - Alexei Kaigorodov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接