Объяснение того, как загрузчик классов загружает статические переменные - PullRequest
9 голосов
/ 15 июля 2009

Хорошо, так что это вопрос новичка на Java, но я не могу разобраться с этим.

У меня есть следующий код внутри моего класса

private static final String [] LIST_CODE = gerarListCode();
private static final int [][] LIST_INTEGER = new int [][] {
        {947,947}, {110,103}, 
        {947,958}, {110,120}, 
        {947,954}, {103,107}, 
        {947,967}, {110,99,104}};

 private static String [] gerarListCode()
    {
        String [] listCode = new String [LIST_INTEGER.length];

        for (int i=0 ; i<LIST_INTEGER.length ; i++)
        {
           //do some stuff      
        }

        return listaUnicode;
    }

Этот код дает мне исключение инициализации из-за nullpointerexception в следующей строке

 String [] listCode = new String [LIST_INTEGER.length];

Кажется, что переменная LIST_INTEGER в это время пуста.

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

Ответы [ 2 ]

11 голосов
/ 15 июля 2009

Да, короче говоря, это линейно.

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

Взято с Java в двух словах.

http://www.developer.com/java/other/article.php/2238491

Вы должны определить переменные и затем инициализировать их в статическом блоке intitializer в правильном порядке, или вы можете поменять местами операторы следующим образом:

private static final int [][] LIST_INTEGER = new int [][] { {947,947}, {110,103}, 
        {947,958}, {110,120}, 
        {947,954}, {103,107}, 
        {947,967}, {110,99,104}};

private static final String [] LIST_CODE = gerarListCode(); 
4 голосов
/ 15 июля 2009

JVM действительно инициализирует статические поля в том порядке, в котором они встречаются.

Статические поля класса инициализируются, когда класс впервые встречается с JVM. Согласно Java Puzzlers , пазл 49 (который ссылается на JLS 4.12.5), статические поля сначала устанавливаются в значения по умолчанию. Переменные объекта установлены на null, int s установлены на 0 и т. Д. После этого их инициализаторы выполняются в порядке появления.

Итак, в вашем примере LIST_CODE и LIST_INTEGER сначала установлены на null. Затем LIST_CODE инициализируется путем вызова gerarListCode(). LIST_INTEGER по-прежнему null, когда этот метод выполняется. Только после этого LIST_INTEGER инициализируется литеральным значением, которое вы даете в своем примере.

...