不一致的类层次结构

4
我已经阅读了有关类构造函数的文章,在这里,然后就会出现以下层次结构为什么是不正确的问题:
public class Test extends Subclass.Inner{ //compile-time error 
                           //The hierarchy of the type Test is inconsistent
    public Test() {
        super();
    }
}


public class Subclass extends Test{
    public class Inner{
    }
}

正式规定:

如果超类构造函数调用语句是未限定的,并且 S 是内部成员类,则在以下情况下会发生编译时错误:如果 S 不是 C 的词法封闭类的声明或继承的成员,则会发生编译时错误。

据我所知,这个例子完全符合我引用的规则。在这种情况下,SubClass 通过继承是 Test 的词法封闭类。为什么代码不能正常工作?您能提供一个恰当的例子来反映这一点吗?

3个回答

2

内部实例类(非静态)实际上是这样转换的:

public class Subclass extends Test {
    public class Inner {
    }
}

变成类似这样的东西:
public class Subclass extends Test {

}

public class Inner {
    Subclass parent;
    public Inner(Subclass parent) {
        this.parent = parent;
    }
}

以下是有效的:
public class Container extends Subclass {
    public class Test extends Subclass.Inner {
        public Test() {
            super();
        }
    }
}

public class Subclass {
    public class Inner {
    }
}

2

内部类的实例必须有一个封闭实例,在内部类实例化之前初始化。另一方面,超类构造函数总是在子类构造函数之前执行。因此,创建SubClass的实例需要首先调用Test的构造函数,这需要首先调用SubClass.Inner的构造函数,但是SubClass.Inner在其包含实例之前无法初始化。

我认为为了满足您引用的条件,超类Inner必须由Test的超类封闭。在您的情况下,它被Test的子类所封闭。


1

这里有一个你错过的条款(8.4.1):

如果T作为超类或超接口的限定符,或者作为C的extendsimplements子句中的超类或超接口出现,那么类C会直接依赖于类型T。

如果满足以下任一条件,则类C会依赖于引用类型T:

  • C直接依赖于依赖于T的类D(递归使用此定义)。

如果一个类依赖于自身,则会在编译时出现错误。

这是因为Subclass的超类声明包含Subclass作为超类名称的限定符

除了你这里极其奇怪的循环定义之外,这是一个编译时错误。 Test 将成为其自身的外部范围。

这个也无法编译,虽然不像内部类那样令人困惑:

class Test implements Test.ITest {
    interface ITest {}
}

Netbeans 给出了更直接的错误提示,即存在“循环继承”。类声明不允许以这种方式引用自身。

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