Когда выполняется статический блок класса?
У меня есть 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).
Поэтому, чтобы статический блок инициализатора выполнялся автоматически, вы должны принудительно активировать один из этих параметров.