статическая переменная с типом класса
class External {
External() { };
static int aaa = 7;
static External tt = new External();
}
public class Main {
public static void main(String[] args) {
External ext = new External();
System.out.println(ext.tt);
System.out.println(ext.tt.tt);
System.out.println(ext.tt.aaa);
System.out.println(ext.tt.tt.aaa);
}
}
вывод у программы будет
External@3feba861
External@3feba861
7
7
Однако если убрать static из объявления переменной tt то возникнет ошибка stackoverflow.
Почему не возникает ошибка при статичной переменной, если там также идет зацикливание вызова, т.е. код
System.out.println(ext.tt.tt.tt.tt.tt.tt.tt.tt.tt.tt.tt.tt.aaa);
так же выдаст 7.
В чем отличие объявления статической и не статической переменной с тем же типом, что и сам класс. Уже башку всю сломал.
Ответы (2 шт):
Если убрать static, то получится класс с полем, которое тот же самый класс. Создается это поле в момент создания объектa класса (до входа в наш конструктоп).
Хорошо.
Создаем объект класса. В момент его создания создается его поле - объект того же типа/класса. У этого поля, естественно, есть поле - объект того же типа, которое тоже создается в момент создания объекта, который его содержит. У этого очередного поля, есть свое поле, и так далее.
Просто получить статическое поле можно как и через класс External.tt так и через объект класса:
External ext = new External();
ext.tt;
Так вот если в External.tt.tt.tt первый раз к полю tt идёт обращение через класс, то последующие обращения .tt происходят через объект класса External (всё время через один и тот же). Естественно, так как tt - static, то происходит создание только одного объекта на класс, поле tt инициализируется только один раз, все tt тут один и тот же объект:
System.out.println(External.tt == External.tt.tt); // true - ссылки одинаковые,
// что значит, что это один и тот же объект
Никакой рекурсии тут нет.