Снова вызвать статический инициализатор - PullRequest
5 голосов
/ 25 марта 2009

Как только класс загружен, есть ли способ снова вызвать статические инициализаторы?

public class Foo {

    static {
        System.out.println("bar");
    }

}

Edit:

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

Ответы [ 6 ]

10 голосов
/ 25 марта 2009

Поместите код инициализации в отдельный общедоступный статический метод, чтобы его можно было вызывать из статического инициализатора и из других источников?

5 голосов
/ 25 марта 2009

Единственное обстоятельство, при котором логика будет выполняться более одного раза, - это если класс загружается несколько раз разными загрузчиками классов. Обратите внимание, что в данном случае это существенно разные классы.

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

4 голосов
/ 25 марта 2009

Я согласен с ответом Эрвикера. Просто извлеките статическую инициализацию в отдельный статический метод.

public class Foo {

    static {
        Foo.initialize();
    }

    public static void initialize() {
        System.out.println("bar");
    }

}
0 голосов
/ 19 ноября 2014

Здесь https://stackoverflow.com/a/19302726/2300018 - это сообщение от меня, в котором я повторно загружаю служебный класс для повторного запуска статического инициализатора для модульного тестирования.

0 голосов
/ 03 октября 2013

Если вы действительно хотите получить точный ответ на свой точный вопрос, ответ - нет. Невозможно вызвать статический инициализатор или instanceInitializer через отражение.

В документах четко сказано:

для getDeclaredMethod(String name):

Если имя "" или "", возникает исключение NoSuchMethodException.

для getDeclaredMethods():

Метод инициализации класса не включен в возвращаемый массив.

Так что нет, его невозможно вызвать, даже с помощью отражения.

0 голосов
/ 26 марта 2009

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

public class OldBadLibraryClass {
   static {
      System.out.println("oldBadLibrary static init");
   }
}

//next file

public class MyBetterClass extends OldBadLibraryClass {
   static {
      System.out.println("MyBetterClass init");
   }
}


public class Test {
   public static void main(String[] args) {
      new MyBetterClass();
   }
}

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

Хотя это совершенно взломанный и довольно хрупкий. Было бы гораздо лучше изменить старый класс, чтобы иметь метод init (), который можно переопределить.

...