Как обрабатывать статический инициализатор конечного поля, который выдает проверенное исключение

Я столкнулся с прецедентом, когда я хотел бы объявить поле static final с инструкцией инициализатора, объявленной для того, чтобы выбросить проверенное исключение. Как правило, это будет выглядеть так:

public static final ObjectName OBJECT_NAME = new ObjectName("foo:type=bar");

Проблема, которую я имею здесь, заключается в том, что конструктор ObjectName может вызывать различные проверенные исключения, которые меня не волнуют (потому что я знаю, что мое имя действительно, и все в порядке, если он с жадностью падает,). Компилятор java не позволит мне просто игнорировать это (как это проверенное исключение), и я бы предпочел не прибегать к:

public static final ObjectName OBJECT_NAME;
static{
    try{
        OBJECT_NAME = new ObjectName("foo:type=bar");
    }catch(final Exception ex){
        throw new RuntimeException("Failed to create ObjectName instance in static block.",ex);
    }  
}

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

Ответ 1

Если вам не нравятся статические блоки (некоторые не делают этого), альтернативой является использование статического метода. IIRC, Джош Блох рекомендовал это (по-видимому, не в Эффективной Java при быстрой проверке).

public static final ObjectName OBJECT_NAME = createObjectName("foo:type=bar");

private static ObjectName createObjectName(final String name) {
    try {
        return new ObjectName(name);
    } catch (final SomeException exc) {
        throw new Error(exc);
    }  
}

Или:

public static final ObjectName OBJECT_NAME = createObjectName();

private static ObjectName createObjectName() {
    try {
        return new ObjectName("foo:type=bar");
    } catch (final SomeException exc) {
        throw new Error(exc);
    }  
}

(Отредактировано: Исправлен второй пример для возврата из метода вместо назначения static.)

Ответ 2

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

Ответ 3

static блоки трудно читать. Поэтому я бы рекомендовал это решение. Однако вы можете обернуть объект в другой объект, например ObjectNameWrapper, который разделяет interface с вашим ObjectName, а конструктор вызывает ваш конструктор ObjectName, скрывая все отмеченные исключения. Но опять же, я бы пошел на статический вариант.