Является ли использование проверенных исключений во внешних API хорошей идеей? - PullRequest
3 голосов
/ 29 июля 2010

Видение проверенного ожидания в API не редкость, один из наиболее известных примеров - IOException в Closeable.close().И часто дело с этим исключением действительно раздражает меня.Еще более раздражающий пример был в одном из наших проектов.Он состоит из нескольких компонентов, и каждый компонент объявляет определенное проверенное исключение.Проблема (на мой взгляд) в том, что во время разработки не было точно известно, какие будут определенные исключения.Так, например, компонент Configurator объявлен ConfiguratorExeption.Когда я спросил, почему бы просто не использовать непроверенные исключения, мне сказали, что мы хотим, чтобы наше приложение было устойчивым и не создавало сбоев во время выполнения.Но это выглядит слабым аргументом, потому что:

  1. Большинство из этих исключений делают приложение непригодным для использования.Да, он не взрывается, но он не может создать ничего, кроме лога наводнения с сообщениями.
  2. Эти исключения не являются конкретными и фактически означают, что «случилось что-то плохое».Как клиент должен восстанавливаться?
  3. Фактически все восстановление состоит из регистрации исключения и последующего его проглатывания.Это выполняется в большом try-catch утверждении.

Я думаю, что это повторяющийся паттерн.Но все еще проверенные исключения широко используются в API.Что является причиной этого?Существуют ли определенные типы API, которые больше подходят для проверенных исключений?

Ответы [ 5 ]

2 голосов
/ 29 июля 2010

Было много споров вокруг этой проблемы.

Взгляните на эту классическую статью на эту тему http://www.mindview.net/Etc/Discussions/CheckedExceptions

Я лично склоняюсь в пользуиспользование Runtime исключений сам и начал считать использование проверенных исключений плохой идеей в вашем API.

На самом деле некоторые очень популярные API Java начали делать то же самое, например, Hibernate прекратил использование проверенных исключений для среды выполнения начиная с версии 3. Платформа Spring также поддерживает использование среды выполнения вместо проверенных исключений.

2 голосов
/ 29 июля 2010

Одна из проблем с большими библиотеками заключается в том, что они не документируют все исключения, которые могут быть сгенерированы, поэтому ваш код может взорваться в любой момент, если недокументированное исключение RuntimeException будет просто сгенерировано из глубокого кода, которым вы не «владеете»".

Явно объявляя все это, по крайней мере, разработчик, использующий указанную библиотеку, может помочь компилятору справиться с ними правильно.

Нет ничего лучше, чем провести судебный анализ в 3 часа утра, чтобы обнаружитьчто в некоторой ситуации возникло такое необъявленное исключение.

2 голосов
/ 29 июля 2010

Проверенные исключения должны быть выброшены только для вещей, которые 1) Исключительные они являются исключением из правила успеха, большинство неудачных бросков исключений - это ужасная привычказащитное кодирование и 2) Действие клиентом .Если что-то случится, что клиент API никак не повлияет, сделайте его RuntimeException.

1 голос
/ 29 июля 2010

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

  • a проверенное исключение представляет собой событие, которое можно разумно ожидать при некоторых предсказуемых, исключительных обстоятельствах, которые все еще находятся "в нормальных рабочих условиях программы / типичного вызывающего абонента", и которые обычно могут быть разобрался не слишком далеко вверх по стеку вызовов;
  • исключение unchecked представляет собой условие, которое мы "не ожидаем" в нормальной рабочей среде программы, и которое может иметь дело с довольно высоким стеком вызовов (или даже возможно, заставит нас закрыть приложение в случае более простого приложения);
  • ru ошибка представляет собой условие, которое, в случае его возникновения, обычно приводит к закрытию приложения.

Например, вполне в пределах типичной среды, в которой при некоторых исключительных, но вполне предсказуемых условиях закрытие файла может вызвать ошибку ввода-вывода (сброс буфера в файл при закрытии, когда диск полный). Поэтому решение позволить Closable выдать проверенный IOException, вероятно, является разумным.

С другой стороны, в стандартных API Java есть несколько примеров, когда решение менее оправданно. Я бы сказал, что API-интерфейсы XML, как правило, чрезмерно суетливы, когда дело доходит до проверенных исключений (почему вы не находите парсер XML, который вы действительно ожидаете и имеете дело с типичным приложением ...?), Как и API-интерфейс отражения (вы как правило, действительно ожидают, что определения классов будут найдены и не смогут работать, независимо от того, не являются ли они ...). Но многие решения спорны.

В целом, я бы согласился с тем, что исключения типа «исключение конфигурации», вероятно, следует не проверять.

Помните, что если вы вызываете метод, который объявляет проверенное исключение, но вы «действительно не ожидаете, что оно будет сгенерировано, и действительно не будете знать, что делать, если оно будет сгенерировано», то вы можете программно «пожать плечами». плечи "и повторно приведите его к RuntimeException или Error ...

0 голосов
/ 29 июля 2010

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

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

Если вы используете проверенные исключения, тогда, по крайней мере, вы будете знать , где и почему ваши абстракции являются дырявыми.ИМХО, это хорошо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...