вы должны знать, что
- первая инструкция в конструкторе вызова конструктора родительского класса
super(params)
или если вы хотите использовать конструктор по умолчанию super()
. В случае конструктора по умолчанию вам не нужно писать его явно.
- код в инициализаторе блоке перемещаются в конструктор сразу после
super(...)
вызова
- статического блок выполняется при инициализации класса, который выполняется после того, как он полностью загружен (с его родительскими классами) по виртуальной машине Java.
Так классы скомпилированы в классы, подобные этому.
public class Parent {
static {
System.out.println("Parent static block");
}
public Parent() {
super();
{
System.out.println("Parent initializer block");
}
System.out.println("Parent constructor");
}
}
public class Son extends Parent {
static {
System.out.println("Son static block");
}
public Son() {
super();
{
System.out.println("Son initializer block");
}
System.out.println("Son constructor");
}
public static void main(String[] args) {
new Son();
}
}
Чтобы быть в состоянии выполнить main
метод из класса Son
нуждается в JVM нагрузки кода этого класса (и классы расширяющим его). После того, как класс полностью загружен JVM инициализирует его статическое содержимое, которое включает в себя выполнение статических блоков (да, в одном классе может быть более одного статического блока). Чтобы полностью загрузить Son
класс JVM должен знать сведения о своем родительском классе, чтобы он полностью загрузил класс Parent
до Son
, что означает, что он также выполнит свои статические блоки перед статическими блоками в классе Son
.
Так выход будет выглядеть следующим образом:
Parent static block
Son static block
Сейчас в main
методе вы вызываете Son
конструктор класса через new Son()
который код выглядит как
super();
{
System.out.println("Son initializer block");
}
System.out.println("Son constructor");
С момента своего super()
см Parent
конструктор класса, который
super();// this will invoke Object constructor since Parent
// doesn't extend anything (which means it extends Object class)
{
System.out.println("Parent initializer block");
}
System.out.println("Parent constructor");
как результат вы увидите
Parent initializer block
Parent constructor
Это ручки Parent#constructor()
выполнена с super()
так рядом ты будешь см код от Son конструкторы после super()
, который будет генерировать
Son initializer block
Son constructor
Чтобы увидеть, что классы будут загружены даже прежде чем использовать Son
конструктор или даже main
метода вы можете просто распечатать что-то перед использованием Son
конструктор, подобный
System.out.println("ABC // before new Son()");
new Son();
, что приведет к
Parent static block
Son static block
ABC // before new Son()
Parent initializer block
Parent constructor
Son initializer block
Son constructor
Вы уже подали ответ на свой вопрос. – jax
Вместо использования чисел используйте собственные имена, такие как статический блок, блок инициализатора, конструктор, чтобы сделать вывод более четким. – Pshemo