Статическая круговая зависимость в Java
Для следующего кода:
class A
{
public static int X;
static { X = B.Y + 1;}
}
public class B
{
public static int Y = A.X + 1;
static {}
public static void main(String[] args) {
System.out.println("X = "+A.X+", Y = "+B.Y);
}
}
выход: X = 1, Y = 2
Зачем? и как???
-Ivar
PS: фрагмент кода взят с JavaCamp.org
3 ответа
Вот что происходит в хронологическом порядке:
Учебный класс
B
содержит метод main, поэтому он загружается загрузчиком классов.Инициализация
B
РекомендацииA
так классA
загружен.A
имеет статическую переменнуюX
инициализирован вB.Y + 1
,Инициализация
B.Y
еще не был выполнен, такB.Y
оценивается в 0, и, таким образом, 1 присваиваетсяA.X
Сейчас
A
завершил загрузку и инициализациюB.Y
может иметь местоЗначение
A.X + 1
(1 + 1) присваиваетсяB.Y
,Значения
A.X
а такжеB.Y
напечатаны как1
а также2
соответственно.
Дальнейшее чтение:
Спецификация языка Java, §12.4.1, когда происходит инициализация
Это только мое предположение:
- Учебный класс
B
загружен, потому что он содержитmain
которую вы просили выполнить. - Загрузчик классов обнаруживает, что
B
требуетA
работать (он используетA
путем доступа к его статическому полю) - Учебный класс
B
загружен. - Учебный класс
A
требует классB
который уже загружен, но еще не инициализирован A
небрежно грузитB.Y
(к тому времени по умолчанию инициализируется 0), поскольку класс выглядит загруженным (недостаток языкового дизайна?)A.X = 0 + 1
A
теперь загружен, загрузчик классов может продолжать загружать и инициализироватьB
B.Y = 1 + 1
,
Публичность B начинает загружаться сама.
Видит AX = BY +1 ==, который равен 0 для начала (значение объекта int по умолчанию), следовательно, 1;
инициализирует B = 1 + 1 = 2;
отсюда и ответ.