Будет ли статический член инициализироваться каждый раз, когда на него ссылаются - PullRequest
0 голосов
/ 28 марта 2019

У нас есть приложение на Java, в котором есть класс Utilities, который содержит несколько статических методов и членов. Один из них инициализируется путем создания другого класса и вызова его метода

private static final Set<Class<? extends AbstractEntity>> ABSTRACT_ENTITIES = new Reflections("something").getSubTypesOf(AbstractEntity.class);

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

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

Я заметил это в профилировщике, когда вызывается один из статических методов. Метод не использует этот конкретный элемент.

Я не заметил какого-либо неправильного поведения (но это большая система, и я новичок), но, похоже, исключение было брошено сотни раз за 20 минут работы локально, а я только делал некоторые очень простые вещи.

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

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

1 Ответ

0 голосов
/ 28 марта 2019

статические конечные переменные инициализируются во время загрузки классов (один раз для ClassLoader). Если во время инициализации возникает исключение, загрузка классов завершится неудачей.

Пример:

package test;

import java.util.Optional;

public class SomeClass {

    private static final Object SOME_VARIABLE = Optional.empty().orElseThrow(RuntimeException::new);

    public static void main(String[] args) {

    }
}

Причины:

java.lang.ExceptionInInitializerError
Caused by: java.lang.RuntimeException
    at java.util.Optional.orElseThrow(Optional.java:290)
    at test.SomeClass.<clinit>(SomeClass.java:7)
Exception in thread "main"

И

package test;

public class SomeClass {

    private static final Object SOME_VARIABLE = new SomeClass();

    public static void main(String[] args) {
        Object a = SomeClass.SOME_VARIABLE;
        Object b = SomeClass.SOME_VARIABLE;

        if (a == b) {
            System.out.println("same instance");
        }
    }
}

Производит:

same instance
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...