2010-08-17 5 views
97

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

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

+0

Аналогичной для статических блоков инициализаторов: http://stackoverflow.com/questions/ 2007666/in-what-order-do-static-initializer-blocks-in-java-run –

ответ

138

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

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

См. JLS 12.4.1.

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

+0

Прохладный за дополнительную информацию. –

+5

+1 для предоставления ссылки JLS – Moshe

+4

Также обратите внимание, что более короткая форма 'Class.forName (className)' также заставляет инициализировать, потому что она эквивалентна 'Class.forName (className, true, currentLoader)'. – user113215

1

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

+0

Есть способы ссылаться на класс без его инициализации. –

11

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

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

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 не был инициализирован.

+6

Строго говоря, инициализация не является «фазой» загрузки классов. В самом деле, некоторые классы * могут * быть загружены, но никогда не инициализированы, если приложение фактически не использует их. –

+0

@ Stephen C Вы правы, я использовал его для отсутствия лучшего термина, может быть, я его процитирую. – naikus

+0

@StephenC это означает, что во время загрузки класса он присваивает память статическим переменным (& методы), но эти статические переменные не инициализируются значениями, указанными в коде? , потому что здесь он выглядит, когда b-> sayHello() -> a, 'a' находится в памяти, но значение для него еще не назначено. –

Смежные вопросы