有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java不一致的类层次结构

我已经阅读了有关类构造函数here的内容,然后出现了一个问题,即为什么以下层次结构不正确:

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{
    }
}

正式地

If a superclass constructor invocation statement is unqualified, and if S is an inner member class, then it is a compile-time error if S is not a member of a lexically enclosing class of C by declaration or inheritance.

我认为这个例子完全符合我引用的规则。在这种情况下,SubClass通过继承在词汇上包含了Test的类。为什么代码不能正常工作?你能提供一个适当的例子来反映这一点吗


共 (3) 个答案

  1. # 1 楼答案

    下面是您缺少的一个子句(8.4.1):

    A class C directly depends on a type T if T is mentioned in the extends or implements clause of C either as a superclass or superinterface, or as a qualifier of a superclass or superinterface name.

    A class C depends on a reference type T if any of the following conditions hold:

    • C directly depends on a class D that depends on T (using this definition recursively).

    It is a compile-time error if a class depends on itself.

    这是一个编译时错误,因为Subclass的超类的声明包含Subclass作为超类名限定符

    除此之外,这里还有一个非常奇怪的循环定义Test本身就是一个外部范围

    这也不会编译,尽管它不像内部类那样令人费解:

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

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

  2. # 2 楼答案

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

    我相信为了满足你所引用的条件,超类内部必须被一个超类测试所包围。在你的情况下,它是由一个子类的测试

  3. # 3 楼答案

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

    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 {
        }
    }