Есть две вещи, о которых вам нужно подумать.
- Порядок инициализации (порядок, в котором значения присваиваются полям)
- Область - где в коде может поле от видел
Если я правильно прочитал ваш вопрос, вы, кажется, думаете, что эти две вещи одинаковы, но на Java они отделены друг от друга.
Хотя сама инициализация находится в порядке строк исходного кода, это не относится к области поля. Поле находится в области видимости во всем теле класса, также до его объявления.
(Аналогично для метода (или любого другого типа члена) - вы можете вызвать метод, который был объявлен после точки вызова.)
Поскольку это находится в области видимости (даже до он объявлен), вы можете назначить это поле в любом месте исходного файла. Вы можете объявить все свои поля в конце файла класса в исходном коде, и это не изменит ситуацию.
Единственный момент, когда это может сбить с толку, - это когда вы назначаете одновременно с объявлением поля. Как это:
public class Snippet {
static {
a = 20;
}
private static int a = 10;
static {
System.out.println(a);
}
public static void main(String[] args) {
System.out.println(Snippet.a);
}
}
Но это не то, что сбивает с толку - просто думать о декларации и задания в виде двух отдельных вещей - декларация в области видимости всего класса, но назначение выполняется в порядке исходного кода. Так private static int a = 10;
можно рассматривать как:
private static int a;
static {
a = 10;
}
Чтобы дать вам справочную ссылку, все это определено в спецификации языка Java. В частности, это в section 6.3 which defines the scoping rules:
Объем заявления члена m
объявленного или унаследованного от типа класса C
(§8.1.6) является все тело C
, в том числе любых вложенных деклараций типа ,
объекты не инициализируются в порядке ваших заявлений; существуют специальные правила, которые последует за компилятором, чтобы правильно инициализировать ваш объект. –