4

以下代码按预期编译:

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

但是,如果我们有 class Bextend class A,我们会收到一个编译错误:

class A {
    class B extends A {}
    class C extends B {}  // <-- Error here
}
由于一些中间体,没有可用的类型 A 的封闭实例
构造函数调用。

这里发生了什么?为什么扩展A会改变什么?

编辑:显然,这在 Java 7 中编译得很好。我希望能解释一下为什么它没有在较旧的 Java 版本中编译,以及 Java 7 中发生了什么变化以允许它。


也可以看看:

4

2 回答 2

5

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.

于 2013-06-13T14:12:45.753 回答
0

这是一个递归。
如果 B 扩展了 A,并且 A 本身有一个新的 B,那么 B 将再次扩展 A,以此类推......

正如@ZiyaoWei 所提到的,当 B 为static. 那是因为 B 类只会存在一次。

于 2013-06-13T14:14:52.580 回答