arshajii
arshajii

Reputation: 129507

Strange compilation error with inner classes

The following code compiles as expected:

class A {
    class B {}
    class C extends B {}
}

But, if we have class B extend class A, we receive a compilation error:

class A {
    class B extends A {}
    class C extends B {}  // <-- Error here
}
No enclosing instance of type A is available due to some intermediate 
constructor invocation.

What is happening here? Why does extending A change anything?

EDIT: Apparently, this compiles fine in Java 7. I would appreciate an explanation as to why it did not compile in older Java versions and what was changed in Java 7 to allow for it.


SEE ALSO:

Upvotes: 4

Views: 158

Answers (2)

zw324
zw324

Reputation: 27190

Since B is not static, it needs some instance of A to be able to exist, thus the error.

If B is static, the error goes away.

Ah, forget about the nonsense. It is a bug, and it works on ideone in Java7 mode. However, prior to Java 7 it does not work - see this question, and you need to either

  1. Change B to static

  2. Add a constructor

    C() {
        A.this.super();
    }
    

And then it will be working.

The reason why this happens before Java 7 might be the following which is from JLS:

Let C be the class being instantiated, let S be the direct superclass of C, and let i be the instance being created.

The implicit super is called on the immediately enclosing instance of i with respect to S.

In the earlier JLS, the immediately enclosing instance is defined as

Let O be the innermost lexically enclosing class of which S is a member, and let n be an integer such that O is the nth lexically enclosing class of C. The immediately enclosing instance of i with respect to S is the nth lexically enclosing instance of this.

However, in Java 7:

Let O be the innermost lexically enclosing class of S, and let n be an integer such that O is the n'th lexically enclosing class of C.

The immediately enclosing instance of i with respect to S is the n'th lexically enclosing instance of this.

So in the past it was the innermost lexically enclosing class of which S is a member while now it is the innermost lexically enclosing class of S, so it changed from C to A, thus the code works in Java 7.

Upvotes: 5

johk95
johk95

Reputation: 953

It's a recursion.
If B extends A, and A has a new B in itself, so that B will extend A again, and so on...

As mentioned by @ZiyaoWei the error goes away when B is static. That's because then the class B will only exist one time.

Upvotes: 0

Related Questions