Статическое и окончательное статическое назначение
Я использовал ту же концепцию, что и в первом классе.
b был инициализирован в 0, и я получил 0 везде, где я использовал b. Через некоторое время я получил причину, запустил отладчик и увидел, что a не было присвоено никакого значения, пока функция не вызовет. У переменной a есть только значение по умолчанию 0.
но когда я запустил класс Test2. Это дало вывод 5.
Я хочу знать, когда произошла эта инициализация? Я знаю, что статические переменные получают значение во время компиляции. Но как насчет статического финала? когда эта переменная получила свое значение?
public class Test1 {
static int b=add();
static int add()
{
return a;
}
static int a=5;
public static void main(String[] args) {
System.out.println(b);
}
}
//Gives output 0
public class Test2 {
static int b=add();
static int add()
{
return a;
}
final static int a=5;
public static void main(String[] args) {
System.out.println(b);
}
}
//gives output 5
3 ответа
final static
поля примитивных и String
типы обрабатываются специально компилятором java: они являются константами времени компиляции. Их значение просто указывается в коде, где он используется. Давайте посмотрим на сгенерированный байт-код.
Test1
учебный класс:
static int add();
Code:
0: getstatic #17 // Field a:I
3: ireturn
Так что это действительно загружает статическое поле.
Test2
учебный класс:
static int add();
Code:
0: iconst_5
1: ireturn
Здесь он просто выдвигает предопределенное постоянное значение 5
даже не ссылаясь на постоянное поле.
Из раздела 12.4.2 Спецификаций языка Java процедура инициализации класса выглядит следующим образом:
- Затем инициализируйте конечные переменные класса и поля интерфейсов, значения которых являются константными выражениями времени компиляции (§8.3.2.1, §9.3.1, §13.4.9, §15.28).
- Затем выполните инициализаторы переменных класса и статические инициализаторы класса или инициализаторы полей интерфейса в текстовом порядке, как если бы они были единым блоком.
Таким образом, финальные переменные будут инициализированы перед статическими переменными. и вы получите вывод 5
,
Просто чтобы добавить к другим ответам:
В вашем первом случае, где a
не является окончательным, b
значение присваивается раньше a
Вот почему вы получаете 0. Последовательность присваивания определяется последовательностью операторов. Если вы двигаетесь static int a=5;
до b
Заявление о назначении вы получите 5.