Статическое и окончательное статическое назначение

Я использовал ту же концепцию, что и в первом классе.
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.

Другие вопросы по тегам