1

My code is as following :-

A class T can extend ClassO.Four. Four is a static class inside ClassO but cannot extend ClassO.Two Two is an inner class inside ClassO. I am getting error

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

What is the reason of difference in behaviour?

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");
    }
}
user207421
  • 305,947
  • 44
  • 307
  • 483

1 Answers1

0

Recall that a static inner class is a "normal" class with the name nested inside its owner class, and additional access privileges to private static members of its owner class. As a result, static inner classes have no restrictions as to the location from which they could be instantiated.

In contrast, a non-static inner class has access to both static and non-static members of its owner class. To make this possible, Java compiler embeds a hidden pointer to the owner into the nested class, and passes an instance of the owner to that constructor.

This behavior relies on the availability of owner's this at the point of instantiation of the non-static inner class. If compiler were to allow you to inherit from a non-static member outside its owner, it wouldn't be able to instantiate your derived class, in effect forcing it to behave as if it were an inner class. That is why the compiler prohibits such inheritance.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thanks for the answer, can you please explain this line more - "This behavior relies on the availability of owner's this at the point of instantiation of the non-static inner class." – springcloudlearner Dec 13 '17 at 20:53
  • @bharatbhushan `class Two` has a hidden member `ClassO _owner_` (the name is probably different, but it is hidden anyway). Its constructor also has a hidden parameter `ClassO owner`. When you write `Two t = new Two();` inside a method of `ClassO`, Java compiler translates it to `Two t = new Two(this);`, so the whole business of manipulating the owner pointer is hidden from you. When the compiler says "No enclosing instance of type ClassO is available," it really says that there's no reference to pass to `Two`'s constructor. – Sergey Kalinichenko Dec 13 '17 at 20:58
  • 'Static inner' is a contradiction in terms, and 'non-static inner' is a tautology: [JLS #8.1.3](https://docs.oracle.com/javase/specs/jls/se9/html/jls-8.html#jls-8.1.3). – user207421 Dec 13 '17 at 22:35
  • ...and yet everyone knows *exactly* what I am talking about, including site visitors with a knack for splitting hairs :-) – Sergey Kalinichenko Dec 14 '17 at 15:25