Почему класс подкласса класса должен быть статическим, чтобы инициализировать подкласс в конструкторе класса? - PullRequest
13 голосов
/ 30 апреля 2010

Итак, вопрос более или менее, как я уже писал. Я понимаю, что это, вероятно, не совсем понятно, поэтому приведу пример.

У меня есть класс Tree и в нем есть класс Node, а пустой конструктор Tree написан:

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 на статический класс, проблем не будет.

Так почему же он работает, когда класс статический?

Кстати, я нашел простое решение для конструктора:

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

Итак, я понятия не имею, в чем проблема в первом куске кода.

Ответы [ 2 ]

24 голосов
/ 30 апреля 2010

По сути, внутренний класс (без модификатора static) имеет неявную ссылку на экземпляр своего внешнего класса, поэтому его нельзя создать, пока не будет создан внешний класс. Создавая его при вызове this, он еще не может ссылаться на внешний класс, потому что внешний класс вообще не создается до тех пор, пока не будет вызван super. В случае, который работает для вас, присваивание заголовку происходит после (неявного) вызова super, поэтому класс создается достаточно, чтобы получить ссылку на него.

Все эти правила не позволяют вам выстрелить себе в ногу, ссылаясь на неинициализированный объект и случая плохие вещи (TM).

0 голосов
/ 12 января 2016

Хорошие новости! Класс подкласса внутреннего класса НЕ ДОЛЖЕН быть статическим!

Вот методика, объясненная Генри Вонгом на ранчо кода, которая работает для внешних классов, которые подклассируют внутренние классы. Для меня это работало хорошо, и всегда интересно посмотреть, как разработчикам языка пришлось искажать 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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...