Оборачивать проверенное исключение в непроверенное исключение в Java? - PullRequest
29 голосов
/ 27 января 2009

У меня есть этот фабричный метод в Java:

public static Properties getConfigFactory() throws ClassNotFoundException, IOException {
    if (config == null) {
        InputStream in = Class.forName(PACKAGE_NAME).getResourceAsStream(CONFIG_PROP);
        config = new Properties();
        config.load(in);
    }
    return config;
}

И я хочу преобразовать два проверенных исключения в непроверенные исключения. Как лучше всего это сделать?

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

Есть ли лучший способ сделать это, или я вообще должен пытаться сделать это в первую очередь?

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

Моя цель - избежать ненужного исключения throws, исключение добавляется в сигнатуру каждого метода, который вызывает мою фабрику.

Ответы [ 4 ]

30 голосов
/ 27 января 2009

A RuntimeException следует использовать только тогда, когда клиент не может восстановиться после любой проблемы. Иногда уместно делать то, о чем вы говорите, но чаще это не уместно.

Если вы используете JDK> = 1.4, вы можете сделать что-то вроде:

try {
  // Code that might throw an exception
} catch (IOException e) {
  throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
  throw new RuntimeException(e);
}

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

Но, как говорили и будут говорить другие, исключения проверяются по причине. Делайте это только в том случае, если вы уверены, что ваши клиенты не могут оправиться от проблемы, которую вы выбрасываете как непроверенное исключение.

ПРИМЕЧАНИЕ. Лучше, чем просто RuntimeException, было бы использовать более конкретное непроверенное исключение, если оно доступно. Например, если единственная причина, по которой ваш метод может выдать ClassNotFoundException, заключается в том, что отсутствует файл конфигурации, вы можете перебросить MissingResourceException, что является непроверенным исключением, но дает дополнительную информацию о том, почему вы его выбрасываете. Другие полезные RuntimeException, которые можно использовать, если они описывают проблему, которую вы выбрасываете, - IllegalStateException, TypeNotPresentException и UnsupportedOperationException.

Также обратите внимание, что ВСЕГДА неплохо, чтобы ваши потоки перехватывали RuntimeException и как минимум регистрировали его. По крайней мере, так вы понимаете, почему ваши темы уходят.

13 голосов
/ 27 января 2009

Два замечания относительно лучших методов обработки исключений:

  • Код вызывающего абонента не может ничего сделать об исключении -> Сделать его непроверенным исключением
  • Код вызывающего абонента предпримет несколько полезных действий по восстановлению на основе информации об исключении -> Сделайте это проверенным исключением

И вы можете выдать исключение RuntimeException с внутренним исключением или без него, в зависимости от того, что может сделать с ним вызывающая сторона. Если вы не выбрасываете внутреннее исключение, вам следует зарегистрировать его в своем методе, если это важно.

4 голосов
/ 27 января 2009

Вы делаете это правильно.

Чтобы разрешить проверку исключений, но без проверки, вы должны заключить их в не проверенные исключения.

Только помните, исключения проверяются по причине.

1 голос
/ 27 января 2009

Если вы хотите избежать слишком большого числа try - catch, поймайте оба исключения на самой фабрике и обработайте их там. Возможно, верните реализацию по умолчанию.

У вас есть для обработки исключений, здесь или где-то еще.

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

В любом случае, вызывающая (бизнес-функция) не будет иметь понятия о том, что должно быть сделано, когда он встречает ClassNotFoundException.

...