Как обрабатывать статический инициализатор конечного поля, который выдает проверенное исключение
Я столкнулся с прецедентом, когда я хотел бы объявить поле 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
, скрывая все отмеченные исключения. Но опять же, я бы пошел на статический вариант.