Шрифт:
В результате выполнения данной программы получается следующий результат: Receiving О Can't divide by Zero! Leaving try. Receiving 1 No matching element found. Leaving try. Receiving 2 Leaving try.
Нетрудно заметить, что блок finally выполняется независимо от того, каким об¬ разом завершается блок try/catch. Использование ключевого слова throws
Иногда исключения нецелесообразно обрабатывать в том методе, в котором они возникают. В таком случае их следует указывать с помощью ключевого слова throws. Ниже приведена общая форма объявления метода, в котором присутствует ключевое слово throws. возвращаемый_тип имя_метода(список_параметров) throws список_исключений { // Тело метода }
В списке исключений через запятую указываются исключения, которые может генерировать метод.
Возможно, вам покажется странным, что в ряде предыдущих примеров ключевое слово throws не указывалось при генерировании исключений за пределами методов. Дело в том, что исключения, генерируемые подклассом Error или RuntimeException, можно и не указывать в списке оператора throws. Исполняющая система Java по умолчанию предполагает, что метод может их генерировать. А исключения всех остальных типов следует непременно объявить с помощью ключевого слова throws. Если этого не сделать, возникнет ошибка при компиляции.
Пример применения оператора throws уже был представлен ранее в этой книге. Напомним, что при организации ввода с клавиатуры в метод main потребовалось включить следующее выражение: throws java.io.IOException
Теперь вы знаете, зачем это было нужно. При вводе данных может возникнуть исключение IOException, а на тот момент вы еще не знали, как оно обрабатывается. Поэтому мы и указали, что исключение должно обрабатываться за пределами метода main . Теперь, ознакомившись с исключениями, вы сможете без труда обработать исключение IOException самостоятельно.
Рассмотрим пример, в котором осуществляется обработка исключения IOException. В методе prompt отображается сообщение, а затем выполняется ввод символов с клавиатуры. Такой ввод данных может привести к возникновению исключения IOException. Но это исключение не обрабатывается в методе prompt . Вместо этого в объявлении метода указан оператор throws, т.е. обязанности по обработке данного исключению поручаются вызывающему методу. В данном случае вызывающим является метод main , в котором и перехватывается исключение. // Применение ключевого слова throws, class ThrowsDemo { // Обратите внимание на оператор throws в объявлении метода. public static char prompt(String str) throws java.io.IOException { System.out.print(str + ": "); return (char) System.in.read ; } public static void main(String args[]) { char ch; try { // В методе prompt может быть сгенерировано исключение, // поэтому данный метод следует вызывать в блоке try. ch = prompt("Enter a letter"); } catch(java.io.IOException exc) { System.out.println("I/O exception occurred."); ch = 'X'; } System.out.println("You pressed " + ch); } }
Обратите внимание на одну особенность приведенного выше примера. Класс IOException относится к пакету java. io. Как будет разъяснено в главе 10, в этом пакете содержатся многие языковые средства Java для организации ввода-вывода. Следовательно, пакет java.io можно импортировать, а в программе указать только имя класса IOException. Новые средства обработки исключений, внедренные в версии JDK 7
С появлением версии JDK 7 механизм обработки исключений в Java был значительно усовершенствован благодаря внедрению трех новых средств. Первое из них поддерживает автоматическое управление ресурсами, позволяющее автоматизировать процесс освобождения таких ресурсов, как файлы, когда они больше не нужны. В основу этого средства положена расширенная форма оператора try, называемая оператором try с ресурсами и описываемая в главе 10 при рассмотрении файлов. Второе новое средство называется многократным перехватом, а третье — окончательным или более точным повторным генерированием исключений. Два последних средства рассматриваются ниже.
Многократный перехват позволяет перехватывать два или более исключения одним оператором catch. Как пояснялось ранее, после оператора try можно (и даже принято) указывать два или более оператора catch. И хотя каждый блок оператора catch, как правило, содержит свою особую кодовую последовательность, нередко в двух или более блоках оператора catch выполняется одна и та же кодовая последовательность, несмотря на то, что в них перехватываются разные исключения. Вместо того чтобы перехватывать каждый тип исключения в отдельности, теперь можно воспользоваться единым блоком оператора catch для обработки исключений, не дублируя код.
Для организации многократного перехвата следует указать список исключений в одном операторе catch, разделив их типы оператором поразрядного ИЛИ. Каждый параметр многократного перехвата неявно указывается как final. (По желанию модификатор доступа final можно указать и явным образом, но это совсем не обязательно.) А поскольку каждый параметр многократного перехвата неявно указывается как final, то ему нельзя присвоить новое значение.
В приведенной ниже строке кода показывается, каким образом многократный перехват исключений ArithmeticException и ArraylndexOutOfBoundsException указывается в одном операторе catch. catch(final ArithmeticException | ArraylndexOutOfBoundsException e) {
Ниже приведен краткий пример программы, демонстрирующий применение многократного перехвата исключений. // Применение средства многократного перехвата исключений. // Примечание: для компиляции этого кода требуется JDK 7 // или более поздняя версия данного комплекта, class MultiCatch { public static void main(String args[]) { int a=88, b=0; int result; char chrs[] = { 'А', 'В', 'C' }; for(int i=0; i < 2; i++) { try { if (i == 0) // сгенерировать исключение ArithmeticException result = а / b; else // сгенерировать исключение ArraylndexOutOfBoundsException chrs[5] = 'X'; } // В этом операторе catch организуется перехват обоих исключений, catch(ArithmeticException | ArraylndexOutOfBoundsException е) { System.out.println("Exception caught: " + e); } } System.out.println("After multi-catch."); } }