2015-02-03 2 views
0

Мне нужно работать с кучей статических классов устаревших, содержащих static блоков. Классы сами по себе являются только вспомогательными классами с использованием только статических методов.Как инициализировать статические блоки?

Пример:

public abstract class Legacy { 
    protected static final String[] ARRAY; 

    static { 
     //init that ARRAY 
    } 

    public static String convert(String value) { 
     //makes use of the ARRAY variable 
    } 
} 

Важно: У меня нет контроля над источниками и, таким образом, не может изменить код. Я знаю, что это серьезный недостаток дизайна в том, как создается класс.

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

Но как я мог это сделать?

Я попытался следующим образом:

Legacy.class.newInstance(); 

Но это приводит к следующей ошибке:

java.lang.InstantiationException 
    at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526) 
    at java.lang.Class.newInstance(Class.java:374) 

Так что, вероятно, что я делаю неправильно?

+1

Статический метод и поля класса сначала инициализируются загрузчиком класса java, когда класс впервые ссылается на код. – kai

+1

Ну, так как это просто обход другой проблемы, мы должны сосредоточиться на главной проблеме, не так ли? Какое исключение вы упомянули? («Я получаю исключения, если класс еще не инициализирован») – Tom

+2

Статические инициализаторы будут запускаться только один раз, в одном потоке ... возможно, вы могли бы привести несколько примеров того, о чем вы говорите. Попытка построить * экземпляр * класса без доступных конструкторов - не очень хорошая идея. –

ответ

1

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

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

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

Похоже, что ваш метод convert делает то, что не является потокобезопасным, например, модифицирует массив.

0

Если вы вызываете только статические методы устаревших классов, нет необходимости создавать экземпляр. Статический блок будет выполняться только один раз (JVM позаботится об этом).

См. Этот небольшой пример.

class Legacy { 
    static { 
     System.out.println("static initializer of Legacy"); 
    } 

    public static void doSomething() { 
     System.out.println("Legacy.doSomething()"); 
    } 
} 

class LegacyDemo { 
    public static void main(String[] args) { 
     Legacy.doSomething(); 
    } 
} 

При запуске LegacyDemo он напечатает

static initializer of Legacy 
Legacy.doSomething() 
Смежные вопросы