Хорошо было бы, если бы в нашем коде никогда не было ошибок, но это маловероятно. Иногда все происходит не так, как мы предполагали, а иногда проблема хуже, чем просто выдача нежелательных результатов. Когда это происходит, JRE генерирует исключительную ситуацию.
Язык имеет некоторые специальные выражения, позволяющие вам перехватить исключительную ситуацию и обработать ее соответствующим образом. Вот общий формат для этих выражений:
try { выражение (выражения) } catch ( exceptionType name ) { выражение (выражения) } finally { выражение (выражения) }
Выражение try заключает в себе код, который может сгенерировать исключительную ситуацию. Если это происходит, управление передается непосредственно в блок catch , известный также под названием обработчик исключительных ситуаций. После выполнения всех попыток и перехватов управление передается в блок finally , независимо от того, генерировалась ли исключительная ситуация. Когда вы перехватываете исключительную ситуацию, то можете попытаться исправить ситуацию либо корректно выйти из программы (или метода).
Обработка исключительных ситуаций
Попробуйте провести следующий эксперимент в main() :
public static void main(String[] args) { Adult myAdult = new Adult(); myAdult.addMoney(1); String wontWork = (String) myAdult.getWallet().get(0); }
При выполнении этого кода мы получим исключительную ситуацию. На консоли отобразится следующая информация:
java.lang.ClassCastException at intro.core.Adult.main(Adult.java:19) Exception in thread "main"
Эта трассировка стека отображает тип исключительной ситуации и номер строки, в которой она возникла. Помните, что мы должны выполнить приведение типа при удалении Object из Collection . У нас есть коллекция элементов Integer , но мы пытаемся получить первый элемент при помощи метода get(0) (где 0 ссылается на индекс первого элемента в списке, потому что список начинается с нулевого индекса, аналогично массиву) и привести его к типу String . Система времени исполнения Java выводит предупреждение. Сейчас программа просто аварийно завершается. Давайте сделаем это завершение более изящным, обрабатывая исключительную ситуацию:
try { String wontWork = (String) myAdult.getWallet().get(0); } catch (ClassCastException e) { System.out.println("You can't cast that way."); }
Здесь мы перехватываем исключительную ситуацию и выводим красивое сообщение. В качестве альтернативы мы могли бы ничего не делать в блоке catch , а выводить красивое сообщение в блоке finally , но в этом не было необходимости. В некоторых случаях объект исключительной ситуации (обычно, но не обязательно, обозначаемый e или ex ) может предоставлять вам больше информации об ошибке, которая может помочь вам отобразить более подробную информацию или восстановить ситуацию.
Иерархия исключительных ситуаций
Язык Java поддерживает полную иерархию исключительных ситуаций. Это значит, что существует много типов исключительных ситуаций. На самом высоком уровне некоторые исключительные ситуации проверяются компилятором, а некоторые, называемые RuntimeException , — нет.
Правилами языка предусмотрено, что вы должны перехватывать или указывать ваши исключительные ситуации. Если метод может сгенерировать отличную от RuntimeException исключительную ситуацию, он должен либо обработать ее, либо указать, что обработать ее должен вызывающий метод. Это делается при помощи указания выражения throws в сигнатуре метода. Например:
protected void someMethod() throws IOException
В вашем коде при вызове метода, указывающего, что он генерирует один или несколько типов исключительных ситуаций, вы должны как-то их обрабатывать, либо добавить ключевое слово throws к сигнатуре вашего метода для ее передачи по стеку вызовов выше, в методы, вызывающие ваш код.
При возникновении исключительной ситуации система времени исполнения Java будет искать обработчик этой исключительной ситуации по стеку выше, если такой обработчик отсутствует в месте возникновения исключительной ситуации. Если обработчик найден не будет при прохождении вплоть до вершины стека, исполняющая система тут же аварийно завершит программу.
Хорошей новостью является то, что большинство IDE (среди них, естественно, и Eclipse) предупредит вас о том, что нужно обработать исключительную ситуацию, генерируемую вызываемым методом. Вы можете решить, что делать.
Тема обработки исключительных ситуаций, естественно, намного шире, но это слишком много для данного руководства. Надеюсь, что рассмотренные нами вопросы помогут вам знать, чего ожидать.