2009-12-08 5 views
31

Я столкнулся с прецедентом, в котором я хотел бы объявить поле 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); 
    } 
} 

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

+0

Мое личное решение бросить 'CheckedExceptionsAreAPainInTheAssSometimesException', который является исключение. Затем программа просто сработает. – Airhead

ответ

40

Если вам не нравятся статические блоки (некоторые люди этого не делают), то альтернативой является использование статического метода. IIRC, Джош Блох рекомендовал это (видимо, не в Effective 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

Я не думал об этом, несмотря на то, что теперь, когда я его прочитал, я на 100% уверен, что давно использовал этот подход. Я буду использовать это, так как мне не нравятся статические блоки, а также как мой код, который можно прочитать новичкам (вы никогда не знаете, кто сохранит ваш код после себя :)). – Romain

+0

дает мне ошибку компилятора «должен возвращать результат типа ObjectName» - было бы простым решением иметь «return null» в блоке 'catch'?Но потом немного странно отлаживать – mmcrae

+0

Я думаю, что вы имеете в виду пункт 59: Избегайте ненужного использования проверенных исключений (Effective Java, 2nd Edition). В этом вопросе Блох советует автору кода, который выдает исключение, чтобы рассмотреть вопрос о том, могут ли его клиенты предпринять какое-то полезное действие после столкновения с исключением ». Это отличается от этого случая, когда вопрос заключается не в легитимности вызываемого исключения, а в том, как лучше всего справляться с этим исключением. От взгляда на документацию для 'java.lang.Error', я получаю ощущение, что ошибка - это не самое лучшее, что можно сделать здесь. – nullstellensatz

5

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

+2

Представление другого объекта кажется тупым. –

+1

Я, безусловно, согласен с вами. Ваше статическое предложение метода лучше. – Bozho

16

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

+0

Это очень актуальный вопрос (поэтому я проголосовал за него, несмотря на то, что не принял его), а также GPP. Я не буду использовать этот метод, потому что, как вы говорите, это трудно понять/прочитать для новичков ... И я не могу гарантировать, что люди, которые будут поддерживать его после меня, будут опытными :). – Romain

+0

Я не уверен, предпочитаю ли я это. С рефакторингом в «частный статический» метод вы рискуете потерять контроль. Обычная практика заключается в том, что эти методы (методы утилиты) размещаются на всем дне класса. Но хорошо, в настоящее время у вас есть IDE, чтобы вы могли просто нажать вперед. – BalusC

 Смежные вопросы

  • Нет связанных вопросов^_^