Когда происходит инициализация статического класса?
Когда инициализируются статические поля? Если я никогда не создавал экземпляр класса, но я обращаюсь к статическому полю, ВСЕ ВСЕ статические блоки и частные статические методы, используемые для создания экземпляров частных статических полей, называемых (в порядке) в этот момент?
Что делать, если я вызываю статический метод? Он также запускает все статические блоки? До метода?
Ответы
Ответ 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
Да, все статические инициализаторы запускаются до первого доступа к классу. Если бы это было иначе, я бы назвал это ошибкой.