Исключения Java: быть или не быть (проверено)?

В Java существует два типа исключений:

  • Проверено — эти исключения проверяются компилятором. Когда вы бросаете его, вам нужно поймать его в блоке try/catch или пометить метод объявлением throws, иначе ваш код не скомпилируется. Проверенные исключения — это те, которые получены из класса Exception.
  • Unchecked — они вообще не проверяются во время компиляции. Вы можете использовать их без блока try/catch или даже без объявления throws. Если вы хотите создать его, вы должны получить его из класса RuntimeException. Сама среда выполнения Java также определяет непроверенные исключения из класса Error. Их можно рассматривать как третий тип, но мы их не выбрасываем.

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

Непроверенные исключения

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

Давайте посмотрим на некоторые из них:

  • NullPointerException: это мое любимое, оно происходит, когда вы вызываете метод или пытаетесь получить доступ к свойству ссылки, которая в основном пуста. Но вы могли бы проверить это раньше. Поэтому когда возникает исключение NullPointerException, это в основном потому, что вы ленились его проверить или убедиться, что этого не произойдет.
  • ArithmeticException: еще один приятный момент. Это происходит, когда вы делаете что-то неприятное с точки зрения арифметики, например, когда пытаетесь что-то разделить на ноль. Я не могу достаточно повторяться: с какой стати вы не проверили, что делитель равен нулю?
  • IndexOutOfBoundsException: это происходит, когда вы пытаетесь получить доступ к индексу, находящемуся за пределами контейнера (строки или массива). Позор тебе!
  • UnsupportedOperationException: Ну, это что-то особенное в том смысле, что это не потому, что вы лично что-то напортачили. Это потому, что создатели среды выполнения Java пытались внести обратно совместимые изменения, и поэтому они испортили API коллекций чем-то, что просто не подходило. За исключением того, что вы бросаете это вручную, потому что тогда вы нарушаете правила интернет-провайдера и ... вы знаете.

Итак, решение для такого рода исключений? Меры предосторожности.

Что касается ошибок: не пытайтесь их отловить! Просто нет. Это указывает на более серьезные проблемы, чем вы могли бы решить внутри JVM.

Проверенные исключения

Как насчет проверенных исключений? Вы просто не можете подготовиться к ним. Они случаются по внешней причине.

  • IOException: Ой. Мы могли бы подумать, что сеть есть всегда, наш жесткий диск предоставлен, никто больше не удаляет файлы, которые мы собираемся прочитать, но иногда... ну, дерьмо случается.
  • SQLException:Ах, мы почти забыли нашего заклятого врага. Мы сталкиваемся с этим, когда запрос перепутан, таблица содержит другой тип, который мы пытаемся извлечь, и так далее. Нет способа получить доступ к SQL мирным путем. Исключение или набор результатов. Твой выбор.
  • ScriptException: Боже, зачем вообще это Java? Это происходит, когда базовый интерпретатор сценариев не может интерпретировать или запустить некоторые сценарии. Опять же, как вы можете проверить, содержит ли какой-либо фрагмент JavaScript синтаксические ошибки или ошибки времени выполнения, не интерпретируя и не выполняя его? Да, регулярное выражение! Нет.

Таким образом, мы оказались без надлежащих мер предосторожности для решения проблем, которые могут вызвать проблемы, перечисленные выше. Поэтому мы должны следовать этой идее и использовать проверенные, когда вы просто не можете предоставить способ создать надежное решение. Во всех остальных случаях вы должны придерживаться непроверенных и производных от класса RuntimeException.

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

Так что в следующий раз, когда будете создавать исключение в Java, остановитесь на минутку и задайте себе вопрос:

  • Мог ли клиент этого метода принять меры предосторожности, чтобы избежать этой ошибки? Да? Сделайте его непроверенным.
  • Эта проблема возникает из-за внешних факторов, таких как ввод-вывод или произвольные параметры, и ее нельзя предсказать? Сделайте это проверенным.