What is the difference between a static and a non-static initialization code block
В чем разница между статическим и нестатическим блоками кода инициализации
Мой вопрос касается одного конкретного использования ключевого слова static. Можно использовать static ключевое слово для покрытия блока кода внутри класса, который не принадлежит ни одной функции. Например, следующий код компилируется:
Если вы удалите static ключевое слово, оно будет жаловаться, потому что переменная a является final. Однако можно удалить оба final и static ключевые слова и заставить его компилироваться.
Меня это сбивает с толку обоими способами. Откуда у меня должен быть раздел кода, который не принадлежит ни одному методу? Как его можно вызвать? В общем, какова цель такого использования? Или лучше, где я могу найти документацию по этому поводу?
Переведено автоматически
Ответ 1
Блок кода со статическим модификатором обозначает инициализатор класса; без статического модификатора блок кода является инициализатором экземпляра.
Инициализаторы класса выполняются в том порядке, в котором они определены (сверху вниз, точно так же, как простые инициализаторы переменных), когда класс загружен (на самом деле, когда он разрешен, но это формальность).
Инициализаторы экземпляра выполняются в порядке, определенном при создании экземпляра класса, непосредственно перед выполнением кода конструктора, сразу после вызова суперконструктора.
Если вы удалите static из int a, это станет переменной экземпляра, к которой вы не сможете получить доступ из блока статического инициализатора. При этом произойдет сбой компиляции с ошибкой "на нестатическую переменную a нельзя ссылаться из статического контекста".
Если вы также удалите static из блока инициализатора, он затем становится инициализатором экземпляра и, таким образом, int a инициализируется при построении.
Ответ 2
Уф! что такое статический инициализатор?
Статический инициализатор представляет собой static {} блок кода внутри класса java и выполняется только один раз перед вызовом конструктора или метода main.
ХОРОШО! Расскажите мне больше...
это блок кода static { ... } внутри любого класса Java. и выполняется виртуальной машиной при вызове класса.
Операторы return не поддерживаются.
Аргументы не поддерживаются.
Не this или super поддерживаются.
Хм, где я могу это использовать?
Может использоваться везде, где вам удобно :) вот так просто. Но я вижу, что большую часть времени он используется при подключении к базе данных, инициализации API, ведении журнала и т.д.
Приведенный выше инициализатор экземпляра содержит инструкцию println . Чтобы понять, как это работает, мы можем рассматривать его как инструкцию присваивания переменной, например, b = 0 . Это может сделать его более понятным.
Вместо
int b = 0, вы могли бы написать
int b; b = 0;
Следовательно, инициализаторы экземпляра и инициализаторы переменных экземпляра практически одинаковы.
3. Когда полезны инициализаторы экземпляра?
Инициализаторы экземпляра используются редко, но все же это может быть полезной альтернативой инициализаторам переменных экземпляра, если:
Код инициализатора должен обрабатывать исключения
Выполнять вычисления, которые не могут быть выражены с помощью инициализатора переменной экземпляра.
Конечно, такой код можно было бы написать в конструкторах. Но если бы класс имел несколько конструкторов, вам пришлось бы повторять код в каждом конструкторе.
С помощью инициализатора экземпляра вы можете просто написать код один раз, и он будет выполнен независимо от того, какой конструктор используется для создания объекта. (Я думаю, это всего лишь концепция, и она используется не часто.)
Другой случай, в котором полезны инициализаторы экземпляра, - это анонимные внутренние классы, которые вообще не могут объявлять никаких конструкторов. (Будет ли это хорошим местом для размещения функции ведения журнала?)
Спасибо Derhein.
Также обратите внимание, что анонимные классы, реализующие интерфейсы [1], не имеют конструкторов. Следовательно, инициализаторы экземпляра необходимы для выполнения любых типов выражений во время построения.