Я смотрел на приведенный ниже код и обнаружил что-то странное:
public class Sequence {
Sequence() {
System.out.print("c ");
}
{
System.out.print("y ");
}
public static void main(String[] args) {
new Sequence().go();
}
void go() {
System.out.print("g ");
}
static {
System.out.print("x ");
}
}
Я ожидал, что это приведет к ошибке компиляции, так как System.out
с "y" не принадлежит просто объявлению метода a { }
. Почему это действительно так? Я не понимаю, как этот код должен или должен называться.
При запуске он x y c g
также производит , почему вызывается static { }
перед конструктором последовательности?
источник
the code is copied into the beginning of each constructor of the class
- это неверно. Скажем, конструктор начинается сsuper("x ");
, суперконструктор будет выполняться до любых блоков инициализации.Это не метод, а блок инициализации .
Он будет выполнен перед вызовом конструктора. Пока
- статический блок инициализации, который выполняется, когда класс загружается загрузчиком классов.
Итак, когда вы запускаете свой код
1. Класс загружается загрузчиком классов, поэтому выполняется статический блок инициализации.
Вывод: x выводится на печать.
2. Объект создается, поэтому выполняется блок инициализации, а затем вызывается конструктор.
Вывод: выводится y, за которым следует c
3. Вызывается основной метод, который, в свою очередь, вызывает метод go
Вывод: выводится g.
Конечный результат: xycg
Это может помочь http://blog.sanaulla.info/2008/06/30/initialization-blocks-in-java/
источник
Это блок инициализации экземпляра, за которым следует блок статической инициализации .
вызывается при создании экземпляра класса.
вызывается, когда класс загружается загрузчиком классов. Итак, когда вы это сделаете
класс загружается, поэтому он выполняется
static {}
, затем он выполняет блок инициализации экземпляра{}
, после этого вызывается тело конструктора, а затем метод для вновь созданного экземпляра. Ergo выводx y c g
.источник
Это статический блок, который вызывается во время загрузки класса.
Является ли блок инициализации
У вас может быть несколько блоков инициализации в классе, и в этом случае они выполняются в той последовательности, в которой они появляются в классе.
Обратите внимание, что любой блок инициализации, присутствующий в классе, выполняется перед конструктором.
источник
- это блок инициализации, совместно используемый классом (как обозначено
static
), который выполняется первым.- это блок инициализации, общий для всех объектов (конструкторов) класса, который идет дальше.
- это особый конструктор класса, который выполняется третьим. Блок инициализации экземпляра вызывается первым при каждом выполнении конструктора. Вот почему "y" стоит перед "c".
- это просто метод экземпляра, связанный с объектами, созданными с использованием конструктора выше, который идет последним.
источник
Такие блоки называются
initializer block
. Он выполняется каждый раз, когда вы создаете экземплярclass
. Во время компиляции этот код перемещается в каждый конструктор вашего класса.Где как в случае
static initializer
блокировки: -он выполняется один раз при загрузке класса. Обычно мы используем
static
блок инициализатора, когда инициализацияstatic
поля требует нескольких шагов.источник
Он используется как блок инициализации и запускается после любого статического объявления . Его можно использовать, чтобы гарантировать, что никто другой не сможет создать экземпляр класса (точно так же, как вы использовали бы частный конструктор), как в шаблоне проектирования Singleton .
источник
Static blocks
выполняются только один раз при загрузке класса и инициализируется JRE.И
non-static
блок будет вызываться каждый раз, когда вы создаете новый экземпляр, и он будет вызываться непосредственно перед конструктором.Поскольку здесь вы создали только 1 экземпляр, созданный
Sequence
таким образом, был вызван послеnon-static
блоков, а затем метод, который на самом деле является вашей целью.источник