【问题标题】:Static Nested class can be extended by not non-static [duplicate]静态嵌套类可以通过非非静态扩展[重复]
【发布时间】:2017-12-13 20:35:57
【问题描述】:

我的代码如下:-

一个类T 可以扩展ClassO.FourFourClassO 内部的静态类,但不能扩展 ClassO.Two TwoClassO 内部的内部类。我收到错误

No enclosing instance of type ClassO is available due to some intermediate constructor invocation

行为差异的原因是什么?

class ClassO
{   
    interface inner
    {
        void msg();
    }

    class Two implements inner
    {
        public void msg()
        {
            System.out.println("Class Two");
        }
    }

    static class Four 
    {
        public  void msg()
        {
            System.out.println("Class Four");
        }
    }

    public void m()
    {

    }
}

class T extends ClassO.Two  **// can extend ClassO.Four but not ClassO.Three**
{
    public void msg()
    {
        System.out.println("Class Two");
    }
}

【问题讨论】:

  • `非静态内部'是一个重言式:JLS #8.1.3.
  • 而且你的标题令人费解。

标签: java inheritance inner-classes


【解决方案1】:

回想一下,静态内部类是一个“普通”类,其名称嵌套在其所有者类中,并具有对其所有者类的私有静态成员的额外访问权限。因此,静态内部类对实例化的位置没有任何限制。

相比之下,非静态内部类可以访问其所有者类的静态和非静态成员。为了实现这一点,Java 编译器将一个指向所有者的隐藏指针嵌入到嵌套类中,并将所有者的一个实例传递给该构造函数。

此行为依赖于所有者的this 在非静态内部类的实例化点的可用性。如果编译器允许您从其所有者之外的非静态成员继承,它将无法实例化您的派生类,实际上迫使它表现得好像它是一个内部类。这就是编译器禁止这种继承的原因。

【讨论】:

  • 感谢您的回答,能否请您进一步解释这一行 - “此行为依赖于所有者 this 在非静态内部类的实例化点的可用性。”
  • @bharatbhushan class Two 有一个隐藏成员 ClassO _owner_(名称可能不同,但无论如何它是隐藏的)。它的构造函数还有一个隐藏参数ClassO owner。当您在ClassO 的方法中编写Two t = new Two(); 时,Java 编译器会将其转换为Two t = new Two(this);,因此操作所有者指针的整个业务对您来说是隐藏的。当编译器说“没有可用的 ClassO 类型的封闭实例”时,它确实表示没有引用传递给 Two 的构造函数。
  • “静态内部”在术语上是矛盾的,“非静态内部”是重言式:JLS #8.1.3
  • ...然而每个人都知道确切地我在说什么,包括具有分裂头发诀窍的网站访问者:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-28
  • 2015-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多