Ответ 1
A.f()
в App.main()
запускает инициализацию класса A
.
Все постоянные переменные инициализируются. Единственная постоянная переменная S1
, которая теперь 1
.
Затем остальные статические поля инициализируются в текстовом порядке. b
- это первое поле, которое запускает инициализацию класса b
, которое, в свою очередь, вызывает A.f()
. S2
просто null
, потому что он еще не инициализирован. Инициализация b
завершена. И последнее, но не менее важное: S2
инициализируется объектом Integer
2
.
S2
не является постоянной переменной, потому что это не примитивный тип int
, а ссылочный тип Integer
. S2 = 2;
является сокращением автоматического бокса для S2 = Integer.valueOf(2);
.
Если декларатор в объявлении поля имеет инициализатор переменной, то декларатор имеет семантику присвоения (§15.26) объявленной переменной.
[...]
Обратите внимание, что поля
static
, которые являются постоянными переменными (§4.12.4), инициализируются перед другими полямиstatic
(§12.4.2). Это также применяется в интерфейсах (§9.3.1). Такие поля никогда не будут иметь начальных значений по умолчанию (§4.12.5) даже при использовании коварных программ.
Постоянная переменная является переменной
final
примитивного типа или типаString
, которая инициализируется константным выражением (§15.28). Является ли переменная постоянной переменной или нет, может иметь последствия для инициализации класса (§12.4.1), бинарной совместимости (§13.1, §13.4.9) и определенного назначения (§16 (Определенное назначение)).
Постоянное выражение представляет собой выражение, обозначающее значение примитивного типа или
String
, которое не завершается внезапно и составлено с использованием только следующего:
- Литералы примитивного типа и литералов типа
String
[...]
Для каждого класса или интерфейса C существует уникальная блокировка инициализации
LC
. Отображение от C доLC
остается на усмотрение реализации виртуальной машины Java. Процедура инициализации C следующая:[...]
В противном случае запишите тот факт, что инициализация объекта
Class
для C выполняется текущим потоком и отпуститеLC
.Затем инициализируйте поля
static
C, которые являются постоянными переменными (§4.12.4, §8.3.2, §9.3.1).[...]
- Затем выполните либо инициализаторы переменной класса, либо статические инициализаторы класса, или инициализаторы поля интерфейса, в текстовом порядке, как если бы они были одним блоком.
12.4.2. Подробная процедура инициализации
Каждая переменная в программе должна иметь значение перед его значением:
Каждая переменная класса, переменная экземпляра или компонент массива инициализируется значением по умолчанию при его создании (§15.9, §15.10.2):
[...]
- Для всех ссылочных типов (§4.3) значение по умолчанию
null
.