Подтвердить что ты не робот

В каком порядке статические блоки и статические переменные в классе выполняются?

Возможный дубликат:
Инициализация статического класса Java

Почему переменная строки обновляется в блоке инициализации, а не целое число (даже если блок написан первым)

class NewClass
{
    static 
    {
       System.out.println(NewClass.string+" "+NewClass.integer);
    }

    final static String string="static";
    final static Integer integer=1;

    public static void main(String [] args)//throws Exception
    {
    }
}

Мой вывод

static null

P.S: Также заметили, что инициализация строковой переменной происходит перед блоком только тогда, когда я вставляю последний модификатор. почему это так? почему бы и не целое число? Я также объявил его окончательным статистом

4b9b3361

Ответ 1

Из раздел 12.4.2 JLS, отрезанный соответствующим образом:

Процедура инициализации C следующая:

  • Затем инициализируйте конечные переменные класса и поля интерфейсов, значения которых являются постоянными выражениями времени компиляции (§8.3.2.1, §9.3.1, §13.4.9, §15.28).

  • Затем выполните либо инициализаторы переменной класса, либо статические инициализаторы класса, или инициализаторы поля интерфейса, в текстовом порядке, как если бы они были одним блоком.

Итак, для констант, не связанных с компиляцией, это не случай "всех переменных", а затем "все статические инициализаторы" или наоборот - все они вместе, в текстовом порядке. Итак, если у вас есть:

static int x = method("x");

static {
    System.out.println("init 1");
}

static int y = method("y");

static {
    System.out.println("init 2");
}

static int method(String name) {
    System.out.println(name);
    return 0;
}

Тогда выход будет:

x
init 1
y
init 2

Даже создание окончаний x или y не повлияет на это здесь, поскольку они все еще не будут константами времени компиляции.

P.S: Также заметили, что инициализация строковых переменных происходит перед блоком только тогда, когда я вставляю последний модификатор.

В этот момент это константа времени компиляции, и любые ее применения в основном встроены. Кроме того, значение переменной присваивается перед остальными инициализаторами, как указано выше.

Раздел 15.28 JLS определяет константы времени компиляции - он включает в себя все примитивные значения и String, но не типы обертки, такие как Integer.

Ответ 2

Вот короткий и прямой ответ на ваш вопрос....

static Variable:

static Переменные выполняются, когда JVM загружает Class, а Class загружается, когда, либо его созданный или его static method.

static Block or static Initializer Block:

статический статический блок инициализатора получает инициализацию до Class получает экземпляр или до его static method и Еще до используется его static Variable.

/////////Отредактированная часть /////////

class NewClass {

    final static String string = "static";
    final static Integer integer = 1;

    static {
        System.out.println(NewClas.string + " " + NewClas.integer);
    }

    public static void main(String [] args) { // throws Exception
        new NewClas();
    }

}

Вышеприведённый текст напечатает static 1.

Причина в том, что JVM выполнит процесс оптимизации, известный как Constant folding, выполнив предварительный расчет постоянных переменных.

Кроме того, в в вашем случае результат был static null, причина Constant folding применяется к примитивному типу, а не к объекту Wrapper, в вашем случае его Integer...

Ответ 3

Они инициализируются в заданном порядке (поля и статические блоки), поэтому печатное значение null, ничто не было назначено статическим полям, определенным после статического блока.