В каком порядке статические блоки и статические переменные в классе выполняются?
Возможный дубликат:
Инициализация статического класса 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: Также заметили, что инициализация строковой переменной происходит перед блоком только тогда, когда я вставляю последний модификатор. почему это так? почему бы и не целое число? Я также объявил его окончательным статистом
Ответы
Ответ 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
, ничто не было назначено статическим полям, определенным после статического блока.