Я получил код, похожий на байт-код, здесь ASM.
Я думаю, что это может ответить на ваш вопрос, объясняя, что произошло, когда объект был создан в этом случае.
public class Test {
static <clinit>() : void
GETSTATIC System.out : PrintStream
LDC "3"
INVOKEVIRTUAL PrintStream.println(String) : void
RETURN
<init>() : void
ALOAD 0: this
INVOKESPECIAL Object.<init>() : void
GETSTATIC System.out : PrintStream
LDC "2"
INVOKEVIRTUAL PrintStream.println(String) : void
GETSTATIC System.out : PrintStream
LDC "1"
INVOKEVIRTUAL PrintStream.println(String) : void
RETURN
public static main(String[]) : void
NEW Test
INVOKESPECIAL Test.<init>() : void
RETURN
}
мы можем видеть LDC "3"
находится в "Clinit", это инициализатор класса.
Время жизни объекта обычно таково: класс загрузки -> класс связывания -> инициализация класса -> создание экземпляра объекта -> использование -> GC.Вот почему 3 появляется первым.И поскольку это на уровне класса, а не на уровне объекта, он появится один раз, поскольку тип класса будет загружен один раз.Для получения подробной информации, ссылка на внутри виртуальной машины Java2: время жизни типа
LDC "2"
и `LDC "1"
в конструкторе "init".
Причина в следующем порядке: конструктор сначала выполнит некоторую инструкцию по импликации, такую как супер-конструктор и код в {} класса, а затем выполнит код, который явно указан в их конструкторе.
Это то, что будет делать компиляторв файл Java.