Уместно ли перехватывать java.lang.ExceptionInInitializerError в многопоточном приложении? - PullRequest
0 голосов
/ 08 апреля 2019

У меня есть класс, который загружает и анализирует данные из файлов XML в статическом инициализаторе, например:

class A {
    //static structures to store parsed XML data
    public static int num;
    ...

    static {
        try {
            //load/parse XML data
        catch (Exception e) {
            throw new RuntimeException("...");
        }
    }

    public static void method1() {
        //do some work on data
}

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

class Important {
    ...

    public initCriticalData() {
        try {
            Class A.method();
        catch(java.lang.ExceptionInInitializerError e) {
            //notify user of failure to load/parse XMLs and wait for user to close application
        }
    }
}

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

1 Ответ

0 голосов
/ 08 апреля 2019

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

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

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

Моя рекомендация НЕ будет выполнять инициализацию в статическом инициализаторе, если вы ожидаете, что инициализация может завершиться неудачей из-за того, что делает пользователь.Вместо этого сделайте инициализацию явно;например, при ленивой инициализации при первом вызове метода Singleton getInstance.

...