
Определение enum-класса начинается с его констант, которые инициализируются в статическом блоке инициализации, вызывая свой приватный конструктор.
Поскольку статические блоки инициализации выполняются в порядке их появления в коде, то любой статический блок, добавленный в описание enum-класса, выполнится после того, как будут созданы константы класса. Это хорошо видно, если декомпилировать байт-код enum-класса.
Исходный класс:
enum Level {
BEGINNER, EXPERT;
}
Декомпелированный байт-код:
final class Level extends Enum
{
public static final Level BEGINNER;
public static final Level EXPERT;
private static final Level $VALUES[];
static {
BEGINNER = new Level("BEGINNER", 0);
EXPERT = new Level("EXPERT", 1);
$VALUES = (new Level[]{
BEGINNER, EXPERT
});
}
private Level(String s, int i) {
super(s, i);
}
// остальной код
}
Тогда для такой реализации класса:
enum Level {
BEGINNER, EXPERT;
static {
System.out.println("Static block");
}
{
System.out.println("Init block");
}
Level() {
System.out.println("Constructor");
}
}
При загрузке его в память вывод будет такой:
/*
Init block
Constructor
Init block
Constructor
Static block
*/
Для каждой константы попарно вызвался динамический блок инициализации (выполняется перед конструктором) и конструктор, а статический блок - только один раз и только после всех вызовов конструктора.