Виды исключений catch java

The catch Blocks

You associate exception handlers with a try block by providing one or more catch blocks directly after the try block. No code can be between the end of the try block and the beginning of the first catch block.

try < >catch (ExceptionType name) < >catch (ExceptionType name)

Each catch block is an exception handler that handles the type of exception indicated by its argument. The argument type, ExceptionType , declares the type of exception that the handler can handle and must be the name of a class that inherits from the Throwable class. The handler can refer to the exception with name .

The catch block contains code that is executed if and when the exception handler is invoked. The runtime system invokes the exception handler when the handler is the first one in the call stack whose ExceptionType matches the type of the exception thrown. The system considers it a match if the thrown object can legally be assigned to the exception handler’s argument.

The following are two exception handlers for the writeList method:

try < >catch (IndexOutOfBoundsException e) < System.err.println("IndexOutOfBoundsException: " + e.getMessage()); >catch (IOException e)

Exception handlers can do more than just print error messages or halt the program. They can do error recovery, prompt the user to make a decision, or propagate the error up to a higher-level handler using chained exceptions, as described in the Chained Exceptions section.

Читайте также:  keywords

Catching More Than One Type of Exception with One Exception Handler

In Java SE 7 and later, a single catch block can handle more than one type of exception. This feature can reduce code duplication and lessen the temptation to catch an overly broad exception.

In the catch clause, specify the types of exceptions that block can handle, and separate each exception type with a vertical bar ( | ):

catch (IOException|SQLException ex)

Note: If a catch block handles more than one exception type, then the catch parameter is implicitly final . In this example, the catch parameter ex is final and therefore you cannot assign any values to it within the catch block.

Источник

Виды исключений

Виды исключений в Java

Все исключения делятся на 4 вида, которые на самом деле являются классами, унаследованными друг от друга.

Самым базовым классом для всех исключений является класс Throwable . В классе Throwable содержится код, который записывает текущий стек-трейс вызовов функций в массив. Что такое стек-трейс вызовов, мы изучим немного позднее.

В оператор throw можно передать только объект класса-наследника Throwable . И хотя теоретическим можно написать код вида throw new Throwable(); — так обычно никто не делает. Главная цель существования класса Throwable — единый класс-предок для всех исключений.

Следующим классом исключений является класс Error — прямой наследник класса Throwable . Объекты типа Error (и его классов-наследников) создает Java-машина в случае каких-то серьезных проблем. Например, сбой в работе, нехватка памяти, и т.д.

Обычно вы как программист ничего не можете сделать в ситуации, когда в программе возникла ошибка типа Error : слишком серьезна такая ошибка. Все, что вы можете сделать — уведомить пользователя, что программа аварийно завершается или записать всю известную информацию об ошибке в лог программы.

Исключения типа Exception (и RuntimeException ) — это обычные ошибки, которые возникают во время работы многих методов. Цель каждого выброшенного исключения — быть захваченным тем блоком catch , который знает, что нужно сделать в этой ситуации.

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

Другими словами, если какая-то переменная оказалась равна null , метод выкинет NullPointerException , если в метод передали неверные аргументы — выкинет InvalidArgumentException , если в методе случайно было деление на ноль — ArithmeticException .

RuntimeException — это разновидность (подмножество) исключений Exception . Можно даже сказать, что RuntimeException — это облегченная версия обычных исключений ( Exception ): на такие исключения налагается меньше требований и ограничений

Об отличии Exception и RuntimeException вы узнаете дальше

2. Проверяемые исключения: throws , checked exceptions

Проверяемые исключения: throws, checked exceptions

Все исключения в Java делятся на 2 категории — проверяемые ( checked ) и непроверяемые ( unchecked ).

Все исключения, унаследованные от классов RuntimeException и Error , считаются unchecked-исключениями , все остальные — checked-исключениями .

Спустя 20 лет после введения проверяемых исключений, почти все Java-программисты считают это ошибкой. 95% всех исключений в популярных современных фреймворках — непроверяемые. Тот же язык C#, который чуть ли не скопировал Java подчистую, не стал добавлять checked-исключения .

В чем же основное отличие checked-исключений от unchecked ?

К checked-исключениям есть дополнительные требования. Звучат они примерно так.

Требование 1

Если метод выбрасывает checked-исключение , он должен содержать тип этого исключения в своем заголовке (сигнатуре метода). Чтобы все методы, которые вызывают данный метод, знали о том, что в нем может возникнуть такое «важное исключение».

Указывать checked-исключения надо после параметров метода после ключевого слова throws (не путать со throw ). Выглядит это примерно так:

тип метод (параметры) throws исключение
public void calculate(int n) throws Exception < if (n == 0) throw new Exception("n равно нулю!"); >
public void calculate(n)   if (n == 0) throw new RuntimeException("n равно нулю!"); >

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

Если метод планирует выкидывать несколько checked-исключений , все их нужно указать после ключевого слова throws через запятую. Порядок неважен. Пример:

public void calculate(int n) throws Exception, IOException < if (n == 0) throw new Exception("n равно нулю!"); if (n == 1) throw new IOException("n равно единице"); >

Требование 2

Если вы вызываете метод, у которого в сигнатуре прописаны checked-исключения , то вы не можете проигнорировать этот факт.

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

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

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

public void создатьМир(int n) throws ПустойМир,ОдинокийМир < if (n == 0) throw new ПустойМир("Людей вообще нет!"); if (n == 1) throw new ОдинокийМир("Слишком мало людей!"); System.out.println("Создан прекрасный мир. Население: " + n); >

Вызов этого метода можно обработать 3 способами:

1. Не перехватываем возникающие исключения

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

public void создатьНаселенныйМир(int population) throws ПустойМир, ОдинокийМир < создатьМир(population); >

2. Перехватывать часть исключений

Обрабатываем понятные ошибки, непонятные — прокидываем в вызывающий метод. Для этого нужно добавить их название в throws:

public void создатьНепустойМир(int population) throws ПустойМир < try < создатьМир(population); > catch (ОдинокийМир e) < e.printStackTrace(); >>

3. Перехватываем все исключения

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

public void создатьЛюбойМир(int population) < try < создатьМир(population); > catch(ОдинокийМир e) < e.printStackTrace(); >catch(ПустойМир e) < e.printStackTrace(); >>

3. Множественный перехват исключений

Программисты очень не любят дублирование кода. Даже придумали такой принцип разработки — DRY : Don’t Repeat Yourself. Однако при обработке исключений часто возникают ситуации, когда после блока try следует несколько блоков catch с одинаковым кодом.

Или может быть, например, 3 catch -блока с одним кодом и еще 2 catch -блока с другим. Стандартная в общем-то ситуация, когда у вас в проекте ответственно относятся к обработке исключений.

Начиная с 7-й версии, в язык Java добавили возможность указать несколько типов исключений в одном блоке catch . Выглядит это примерно так:

try < код, где может возникнуть ошибка > catch(ТипИсключения1 | ТипИсключения2 | ТипИсключения3 имя) < код обработки исключений >

Блоков catch может быть сколько угодно. Однако в одном блоке catch нельзя указать исключения, которые наследуются друг от друга. Т.е. нельзя написать catch ( Exception | RuntimeException e), т.к. класс RuntimeException унаследован от Exception .

Источник

Оцените статью