简体   繁体   中英

Why does a sub-class class of a class have to be static in order to initialize the sub-class in the constructor of the class?

So, the question is more or less as I wrote. I understand that it's probably not clear at all so I'll give an example.

I have class Tree and in it there is the class Node, and the empty constructor of Tree is written:

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 gives me the error: "No enclosing instance of type RBTree is available due to some intermediate constructor invocation" for the "new RBTree()" in the empty constructor. However, if I change the RBNode to be a static class, there is no problem.

So why is it working when the class is static.

BTW, I found an easy solution for the cunstructor:

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

So, I have no idea what is the problem in the first piece of code.

Basically an inner class (without the static modifier) has an implicit reference to an instance of its outer class, so it can't be created until the outer class is created. By creating one on the call to this it can't reference the outer class yet because the outer class isn't constructed much at all until after the call to super. The case that works for you, the assignment to head happens after the (implicit) call to super so the class is constructed enough to get a reference to it.

All of these rules prevent you from shooting yourself in the foot by referencing an uninitialized object and having Bad Things (TM) happen.

Good news! The sub-class class of an inner class does NOT have to be static!

Here is a technique explained by Henry Wong at code ranch that works for outer classes that subclass inner classes. It worked well for me and it's always fun to see how the language designers had to contort Java to handle the corner cases :)

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

Here's the example:

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM