Когда выполняется статический блок класса?

У меня есть 2 баночки, назовите их a.jar и b.jar.

b.jar зависит от a.jar.

В a.jar я определил класс, назовем его StaticClass. В StaticClass я определил статический блок, вызывая метод с именем "init":

public class StaticClass {
  static {
    init();
  } 

  public void static init () {
    // do some initialization here
  }
}

в b.jar, у меня есть основной, поэтому в основном я ожидаю, что метод init() был вызван, но на самом деле нет. Я подозреваю, что это потому, что StaticClass не был загружен jvm, может ли кто-нибудь сказать мне

  • Верно ли мое заключение?
  • Что запускает jvm для загрузки класса?
  • Как я могу заставить статический блок выполняться автоматически?

Спасибо

Ответ 1

Да, вы правы. Статические блоки инициализации запускаются, когда JVM (загрузчик класса - конкретный) загружает StaticClass (что происходит при первом обращении к нему в коде).

Вы можете заставить этот метод вызываться явным вызовом StaticClass.init(), который предпочтительнее полагаться на JVM.

Вы также можете попробовать использовать Class.forName(String), чтобы заставить JVM загрузить класс и вызвать его статические блоки.

Ответ 2

Да, вы правы, так как вы не используете свой StaticClass, он не загружается vm, и поэтому init() никогда не выполняется.

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

fooobar.com/questions/82022/...

Ответ 3

Вы правы, самый простой способ получить доступ к классу, например, сделать

StaticClass.class.newInstance();

Или что-то на этот счет в вашем основном методе. Это обеспечит загрузку класса загрузчиком классов.

Ответ 4

Статический код выполняется, когда ссылается ваш класс (StaticClass).

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

Ответ 5

Статический блок выполняется, когда загруженный класс инициализируется или ссылается первым. Класс загрузки не означает, что класс инициализируется. JVM Class Loading - это разные вещи, которые нужно учитывать.

Ответ 6

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

Ответ 7

в основном классе методов b.jar должен автоматически расширять этот StaticClass, что будет активирован статический блок и init()

Ответ 8

Добавление еще нескольких:

статический блок будет выполняться при загрузке jvm класса.

Здесь в вашем примере вы можете вызвать метод init() вашего StaticClass, запуская класс

как   StaticClass staticclass= new StaticClass();

или

StaticClass.class.newInstance(); это более предпочтительно

Ответ 9

Прежде всего, загрузка класса отличается от инициализации класса. Для тех, кто ищет объяснение в спецификации языка Java, когда выполняется статический блок - вот оно.

В §8.7 JLS говорится, что:

Статический инициализатор, объявленный в классе, выполняется, когда класс инициализируется (§12.4.2).

Так что же означает инициализация? Позвольте обратиться к JLS § 12.4.2. Это описывает подробную процедуру инициализации. Однако пункт JLS §12.4.1 может быть более уместным здесь. Это говорит о том, что:

Класс T или интерфейсный тип T будут инициализированы непосредственно перед первым появлением любого из следующего: T является классом, и экземпляр T создан. T является классом, и вызывается статический метод, объявленный T. Статическое поле, объявленное T, присваивается. Используется статическое поле, объявленное T, и поле не является константной переменной (§4.12.4). T является классом верхнего уровня (§7.6), и выполняется утверждение assert (§14.10), лексически вложенное в T (§8.1.3).

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