Когда выполняются эти статические блоки классов и подклассов (для Enum)?

Я пытаюсь определить базовый класс (SubStatus) для Enum.

Когда static блоки называются ниже? Если бы они были классами, а не перечислениями, я полагаю, что они будут вызваны после вызова конструктора классов?

Но потому что они Enumс, разве это не больше похоже на static занятия для начала? Таким образом, возможно, статические блоки выполняются, когда контейнер загружает статические экземпляры?

Подстатус

public enum SubStatus
{
     WAITING(0),
     READY(1);

     protected static final Map<Integer,SubStatus> lookup 
          = new HashMap<Integer,SubStatus>();

     static {
          for(SubStatus s : EnumSet.allOf(SubStatus.class))
               lookup.put(s.getCode(), s);
     }

     protected int code;

     protected SubStatus(int code) {
          this.code = code;
     }

     public int getCode() { return code; }

     public static SubStatus get(int code) { 
          return lookup.get(code); 
     }
}

Статус

public enum Status extends SubStatus
{
     SKIPPED(-1),
     COMPLETED(5);

     private static final Map<Integer,Status> lookup 
          = new HashMap<Integer,Status>();

     static {
          for(Status s : EnumSet.allOf(Status.class))
               lookup.put(s.getCode(), s);
     }

     private int code;

     private Status(int code) {
          this.code = code;
     }

     public int getCode() { return code; }

     public static Status get(int code) { 
          return lookup.get(code); 
     }
}

3 ответа

Статический блок обрабатывается после первого вызова перечисления, но после создания всех значений перечислений. Кстати, ваш код не будет работать. В перечислениях Java нет наследования. Прибегайте к интерфейсам, если вам нужно что-то подобное.

"Конструктор класса" - разговорный термин, имя, согласно спецификации, является статическим инициализатором. На заметку: в Java нет такого понятия, как "статический класс";-)

Перечисления в Java являются классами. Они имеют одинаковую отделку и поведение (у них даже могут быть изменяемые поля, хотя обычно это плохая идея). Они ограничены только в их иерархии типов (они не должны явно расширять другой класс и сами не могут быть явно расширены) и в конструкции (их значения перечисления являются единственными экземплярами, которые когда-либо могут быть созданы).

Поэтому блоки статического инициализатора выполняются так же, как и для обычных классов: когда класс загружается / инициализируется. Это обычно происходит, когда к нему обращаются впервые.

Это порядок:

  1. Enum Constructors

    Конструкторы enum запускаются до инициализации статических полей. Это необходимо, поскольку статические методы должны иметь доступ ко всем значениям перечисления (экземплярам). Перечисляемые значения неявно присваиваются статическим полям.

  2. Статические инициализаторы

    Затем статические инициализаторы и статические блоки вызываются в порядке появления.

Рекомендации:

Другие вопросы по тегам