为什么类的子类类必须是静态的,才能在类的构造函数中初始化子类?

2022-09-04 08:11:22

所以,这个问题或多或少就像我写的。我知道它可能根本不清楚,所以我会举个例子。

我有类树,其中有类Node,并编写了树的空构造函数:

public class RBTree {
    private RBNode head;

    public RBTree(RBNode head,RBTree leftT,RBTree rightT){
        this.head=head;
        this.head.leftT.head.father = head;
        this.head.rightT.head.father = head;
    }

    public RBTree(RBNode head){
        this(head,new RBTree(),new RBTree());
    }

    public RBTree(){
        this(new RBNode(),null,null);
    }  

    public class RBNode{
        private int value;
        private boolean isBlack;
        private RBNode father;
        private RBTree leftT;
        private RBTree rightT;
    }
}

Eclipse给了我一个错误:“由于一些中间构造函数调用”,没有RBTree类型的封闭实例可用“,用于空构造函数中的”new RBTree()”。但是,如果我将RBNode更改为静态类,则没有问题。

那么为什么当类是静态的时,它是如何工作的。

顺便说一句,我为cunstructor找到了一个简单的解决方案:

public RBTree(){
    this.head = new RBNode();
}

所以,我不知道第一段代码中的问题是什么。


答案 1

基本上,内部类(不带静态修饰符)具有对其外部类的实例的隐式引用,因此在创建外部类之前无法创建它。通过在调用时创建一个,它不能引用外部类,因为外部类在调用 super 之前根本没有构造太多。适合您的情况是,对 head 的赋值发生在对 super 的(隐式)调用之后,因此类的构造足以获取对它的引用。this

所有这些规则都阻止你通过引用一个未初始化的对象并让坏事(TM)发生来射击自己的脚。


答案 2

好消息!内部类的子类不必是静态的!

这是Henry Wong在代码牧场解释的一种技术,该技术适用于子类内部类的外部类。它对我来说效果很好,看到语言设计师如何扭曲Java来处理角落情况总是很有趣:)

http://www.coderanch.com/t/588820/java/java/Extend-class-code-top-level#2681401

下面是一个示例:

class Demo extends Main.Inner{
    public Demo(Main outer) {
        outer.super();
    }

    void method(){
        System.out.println(a);
    }
}