Когда происходит инициализация статического класса?

Когда инициализируются статические поля? Если я никогда не создавал экземпляр класса, но я обращаюсь к статическому полю, ВСЕ ВСЕ статические блоки и частные статические методы, используемые для создания экземпляров частных статических полей, называемых (в порядке) в этот момент?

Что делать, если я вызываю статический метод? Он также запускает все статические блоки? До метода?

Ответ 1

Статическая инициализация класса обычно происходит непосредственно перед первым возникновением одного из следующих событий:

  • создается экземпляр класса,
  • вызывается статический метод класса,
  • назначено статическое поле класса,
  • используется не постоянное статическое поле, или
  • для класса верхнего уровня выполняется инструкция assert, лексически вложенная в класс.

См. JLS 12.4.1.

Также можно принудительно инициализировать класс (если он еще не инициализирован) с помощью Class.forName(fqn, true, classLoader) или короткой формы Class.forName(fqn)

Ответ 2

Статические поля инициализируются во время инициализации "фаза" загрузки класса (загрузка, связывание и инициализация), которая включает в себя статические инициализаторы и инициализации его статические поля. Статические инициализаторы выполняются в текстовом порядке, как определено в классе.

Рассмотрим пример:

public class Test {

   static String sayHello()  {
      return a;
   }

   static String b = sayHello(); // a static method is called to assign value to b.
                                 // but its a has not been initialized yet.

   static String a = "hello";

   static String c = sayHello(); // assignes "hello" to variable c

    public static void main(String[] arg) throws Throwable {
         System.out.println(Test.b); // prints null
         System.out.println(Test.sayHello()); // prints "hello"
    }
}

Test.b печатает null, потому что при вызове sayHello в статической области статическая переменная a не была инициализирована.

Ответ 3

Да, все статические инициализаторы запускаются до первого доступа к классу. Если бы это было иначе, я бы назвал это ошибкой.