Подтвердить что ты не робот

Java: в каком порядке инициализируются статические конечные поля?

Хорошо, скажем, у меня есть класс, который выглядит так:

public class SignupServlet extends HttpServlet {
    private static final Logger SERVLET_LOGGER=COMPANYLog.open(SignupServlet.class);
    private static final ExceptionMessageHandler handler = new ExceptionMessageHandler();   
    private static final SignupServletObservableAgent signupObservableAgent = 
        new SignupServletObservableAgent(null, SERVLET_LOGGER);
}

Можно ли рассчитывать на загрузчик классов для инициализации этих полей в порядке, чтобы я мог полагаться на SERVLET_LOGGER для создания экземпляра перед signupObservableAgent?

4b9b3361

Ответ 1

Да, они инициализируются в том порядке, в котором они появляются в источнике. Вы можете прочитать все детали gory в Спецификация языка Java, §12.4.2. См. Шаг 9, который гласит:

... выполняет либо инициализаторы переменной класса, либо статические инициализаторы класса, либо инициализаторы поля интерфейса, в текстовом порядке, как если бы они были одним блоком, за исключением того, что конечные переменные класса и поля интерфейсов, значения которых константы компиляции - сначала инициализируются...

Ответ 2

Я думаю, что инициализация статических полей может быть переупорядочена. По крайней мере, так я понимаю спецификацию JMM

Существует ряд случаев, когда доступ к программным переменным (поля экземпляра объекта, статические поля класса и элементы массива) может казаться выполненным в другом порядке, чем указано программой.

Ответ 3

если существует подкласс и суперкласс.

  • EX: "A" : суперкласс "B": подкласс, и он расширяет суперкласс "A"
  • когда класс B загружается, тогда класс A также загружает
  • все статические переменные получают память со значением по умолчанию из классов "A" и "B"
  • тогда статические члены (статическая переменная, статический блок) выполняются в верхнем и нижнем порядке класса "А", а затем "В", чтобы объявить их. наконец, основной метод, выполняемый из подкласса автоматически.

Ответ 4

Это место, где вы можете использовать статический блок, который гарантировал бы последовательность выполнения.

public class SignupServlet extends HttpServlet {
   private static final Logger SERVLET_LOGGER;
   private static final ExceptionMessageHandler handler;
   private static final SignupServletObservableAgent signupObservableAgent;

   static {
      SERVLET_LOGGER = COMPANYLog.open(SignupServlet.class);
      handler = new ExceptionMessageHandler();
      signupObservableAgent = new SignupServletObservableAgent(null, SERVLET_LOGGER);
   } 
}