Вопрос-ответ

When are static variables initialized?

Когда инициализируются статические переменные?

Мне интересно, когда статические переменные инициализируются их значениями по умолчанию. Правильно ли, что при загрузке класса создаются (выделяются) статические переменные, затем выполняются статические инициализаторы и инициализации в объявлениях? В какой момент задаются значения по умолчанию? Это приводит к проблеме прямой ссылки.

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

Переведено автоматически
Ответ 1

Из Смотрите Методы статических переменных Java:



  • Это переменная, которая принадлежит классу, а не объекту (экземпляру)

  • Статические переменные инициализируются только один раз , в начале выполнения. Эти переменные будут инициализированы первыми, перед инициализацией любых переменных экземпляра

  • Одна копия, которая будет использоваться всеми экземплярами класса

  • Доступ к статической переменной осуществляется непосредственно по имени класса и для нее не требуется никакого объекта.


Переменные экземпляра и класса (статические) автоматически инициализируются стандартными значениями по умолчанию, если вы не смогли их намеренно инициализировать. Хотя локальные переменные не инициализируются автоматически, вы не можете скомпилировать программу, которая не может либо инициализировать локальную переменную, либо присвоить значение этой локальной переменной перед ее использованием.

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

В случае внутренних классов они не могут иметь статических полей


Внутренний класс - это вложенный класс, который не объявлен явно или неявно static.


...


Внутренние классы могут не объявлять статические инициализаторы (§8.7) или интерфейсы-члены...


Внутренние классы могут не объявлять статические члены, если только они не являются постоянными переменными...


Смотрите JLS 8.1.3 Внутренние классы и заключающие их экземпляры

final поля в Java можно инициализировать отдельно от места их объявления, однако это не может быть применимо к static final полям. Смотрите пример ниже.

final class Demo
{
private final int x;
private static final int z; //must be initialized here.

static
{
z = 10; //It can be initialized here.
}

public Demo(int x)
{
this.x=x; //This is possible.
//z=15; compiler-error - can not assign a value to a final variable z
}
}

Это связано с тем, что существует только одна копия static переменных, связанных с типом, а не по одной, связанной с каждым экземпляром типа, как с переменными экземпляра, и если мы попытаемся инициализировать z of type static final внутри конструктора, он попытается повторно инициализировать static final поле типа z, потому что конструктор запускается при каждом создании экземпляра класса, что не должно происходить со статическими final полями.

Ответ 2

Статические поля инициализируются, когда класс загружается загрузчиком классов. В это время присваиваются значения по умолчанию. Это делается в том порядке, в каком они указаны в исходном коде.

Ответ 3

Смотреть:

Последнее, в частности, содержит подробные шаги инициализации, в которых указывается, когда инициализируются статические переменные и в каком порядке (с оговоркой, что final переменные класса и поля интерфейса, являющиеся константами времени компиляции, инициализируются первыми.)

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

Ответ 4

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


  1. Блоки статической инициализации

  2. Блоки инициализации экземпляра

  3. Конструкторы

Детали процесса описаны в документе спецификации JVM.

java