Подтвердить что ты не робот

Практические рекомендации Java при бросании исключений: бросание основных исключений Java

Вместо того, чтобы бросать new Exception("Some message", maybeSomeCause), это означает, что всем вызывающим абонентам моего метода нужно будет ловить исключение (которое может включать RuntimeExceptions), я хотел бы бросить более конкретный тип исключения при возникновении проблемы.

Я могу создать свои собственные типы исключений, которые расширяют исключение или другой тип исключения, но мне любопытно, есть ли хорошая идея повторно использовать некоторые исключения, которые поставляются с основным языком Java, например:

  • IllegalArgumentException
  • UnsupportedOperationException
  • IOException
  • Другие?

Есть ли другие, которых мне не хватает? Я нашел основной список "основных" исключений здесь: http://rymden.nu/exceptions.html с гуманными объяснениями.

Спасибо!

Edit:

Есть ли хороший список "основных" исключений?

Список до сих пор:

4b9b3361

Ответ 1

Да, это очень хорошо. Фактически, это даже написано в "Эффективной Java", 2-е изд. См. Пункт 60 на стр. 248: "Одобрите использование стандартных исключений"

Повторное использование существующих исключений имеет несколько преимуществ. Главный Это упрощает изучение и использование вашего API, поскольку оно соответствует установленных конвенций, с которыми программисты уже знакомы. второй - это то, что программы, использующие ваш API, легче читать потому что они arent cluttered с незнакомыми исключениями. Последний (и меньше), меньшее количество классов исключений означает меньшую площадь памяти и меньше времени, затрачиваемого на загрузку классов.

Ответ 2

Списки, предоставленные в вашем вопросе, не очень полезны в качестве справочных материалов, и большинство описаний в dev-документах кажутся мне загадочными.

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

github gist link (или см. текущий контент ниже)

Список потенциально многоразовых встроенных исключений

организованный оценочной полезностью

IllegalArgumentException

Брошенный, чтобы указать, что метод был передан незаконным или несоответствующим аргументом.

IndexOutOfBoundsException

Брошено указывать, что какой-либо индекс (например, для массива, строки или вектора) находится вне диапазона.

ArithmeticException

Брошенный, когда запрошенная математическая операция нечувствительна или невозможна. Пример: int x = 1/0;

IllegalStateException

Приложение не находится в соответствующем состоянии для запрошенной операции. пример: попытка сохранения до загрузки или создания файла.

DataFormatException

Бросьте это, когда вы получили неверно отформатированные данные. Пример: MyClass.applyJSONString("{non:sense,all,garbled=definitely.not;json{{{")

TimeoutException

Бросьте это, если что-то займет слишком много времени, и вы сдаетесь.

KeySelectorException

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

example: myDataStructure.get("lookup_key");, когда lookup_key не находится в структуре данных.

IOException

У вас есть проблемы с чтением/записью? Выбросьте это исключение.

ScriptException

Запуск script какой-либо формы и обнаружение проблемы с ним (не I/O или синтаксический анализ)? Выбросьте это исключение.

GeneralSecurityException

Бросьте это, если вы столкнулись с проблемой безопасности.

RuntimeException

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

Ответ 3

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

Ответ 4

Большинство основных исключений слишком специализированы для непосредственного использования, если вы не дублируете существующие функции в основных библиотеках. Например, вам, вероятно, никогда не понадобится создать экземпляр UnknownHostException; если сбой разрешения хоста, метод InetAddress или SocketFactory, который вы вызывали, уже создал бы и выдал бы исключение.

Единственными исключениями, которые, как мне кажется, обычно являются полезными, являются IOException, IllegalArgumentException, IllegalStateException и UnsupportedOperationException.

IOException - все проблемы с интерфейсами, сетью и доступом к жесткому диску подпадают под это. Если вы пишете код для доступа к внешним данным или аппаратным средствам, вы должны использовать это. Например, если вы реализуете API для доступа к определенному типу сетевого устройства, вы можете сделать подкласс MyDeviceException, который должен быть выброшен, когда устройство вернет статус ошибки или сделает что-то странное. Также есть случаи, когда вы хотите поймать IOException из одного или нескольких низкоуровневых вызовов библиотеки и перенести его в другой IOException с сообщением более высокого уровня, например, с проверкой подключения, когда выбрано "Устройство недоступно", исключение, вызванное исключением "Истекло время ожидания".

IllegalArgumentException - Любые проверки параметров должны бросать это. Например, отрицательное целое число для параметра размера или неожиданный null. Это неконтролируемое исключение, но я рекомендую документировать его в любом случае, чтобы сделать предварительные условия метода более ясными. Вы можете найти множество примеров в основных библиотеках.

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

UnsupportedOperationException - Если вы создаете подкласс чего-либо, и один из методов суперкласса концептуально недействителен для него, переопределите его и выбросьте один из них. Guava использует это для неизменяемых классов коллекции, поскольку интерфейсы коллекции Java не предназначены для поддержки неизменности. Это, как правило, является признаком плохого дизайна в суперклассе. Не используйте его, если просто ничего не делать или возврат null/empty будет подходящим и неудивительным результатом.

Ответ 5

Если пользователям вашего кода может потребоваться сделать разные вещи на двух разных исключениях, тогда они должны быть разными типами исключений. Тем не менее, исключения JDK охватывают большинство исключений "ошибки программиста" - если, например, генерируется IllegalArgumentException, это указывает на ошибку программирования, а не на то, что должно выполняться во время выполнения.

Ответ 6

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

Очень распространенная ситуация - когда вы открываете API для внешних приложений, ваш API должен быть разработан, чтобы генерировать общие исключения, которые могут быть легко поняты разработчиками, которые его используют.

Например, используйте IllegalArgumentException, когда разработчики передают незаконные аргументы вашему API, IllegalStateException, когда разработчики передают неинициализированный объект и ConcurrentModificationException когда ваш API доступен из нескольких потоков.

Таким образом, разработчики, которые используют ваш API, могут понять, что происходит точно и реагировать соответственно, вместо того, чтобы укладывать время на понимание вашего настраиваемого исключения.

Источник: Эффективное использование исключений