661.11K
Категория: ПрограммированиеПрограммирование

Основы Java. Исключения и их обработка. (Лекция 7)

1.

Седьмая лекция
Exceptions

2.

Исключения и их обработка
Исключениями или исключительными ситуациями называются ошибки,
возникшие в программе во время её работы.
Исключения в Java тоже являются объектами.
Они могут порождаться не только автоматически при возникновении
исключительной ситуации, но и создаваться самим разработчиком, еще
говорят "бросить" от слова "throws", исключительную ситуацию.
В Java есть пять ключевых слов для работы с исключениями:
try - данное ключевое слово используется для отметки начала блока кода,
который потенциально может привести к ошибке.
catch - ключевое слово для отметки начала блока кода, предназначенного
для перехвата и обработки исключений.
finally - ключевое слово для отметки начала блока кода, которое является
дополнительным. Этот блок помещается после последнего блока 'catch'.
Управление обычно передаётся в блок 'finally' в любом случае.
throw - служит для генерации исключений.
throws - ключевое слово, которое прописывается в сигнатуре метода, и
обозначающее что метод потенциально может выбросить исключение с
указанным типом.

3.

Иерархия классов исключений

4.

Исключения делятся на несколько классов, но все они имеют общий
суперкласс - Throwable. Его наследниками являются подклассы Exception и
Error.
Исключения (Exceptions) являются результатом проблем в программе.
Например, произошло деление на ноль в целых числах.
Ошибки (Errors) представляют собой более серьёзные проблемы, которые,
согласно спецификации Java, не следует пытаться обрабатывать в собственной
программе, поскольку они связаны с проблемами уровня JVM.
В Java все исключения делятся на два типа:
- контролируемые исключения (checked), это те, которые должны обрабатываться
блоком catch или описываться в сигнатуре метода.
- неконтролируемые исключения (unchecked), к которым относятся ошибки
(Errors) и исключения времени выполнения (RuntimeExceptions, потомок класса
Exception).
Unchecked могут не обрабатываться и не быть описанными.
К unchecked исключениям относятся, например, NullPointerException,
ArrayIndexOutOfBoundsException, ClassCastExcpetion и так далее.
Это те ошибки, которые могут возникнут практически в любом методе.
Несомненно, описывать каждый метод как тот, который обрабатывает все эти
исключения, не удобно, но если в методе возможна ситуация, которую метод не
в состоянии обработать самостоятельно, он должен "бросать" ошибку.
Но ни в коем случае нельзя использовать исключительные ситуации для
управления ходом выполнения программы.

5.

Пример стандартного обработчика ошибок
class Main {
public static void main(String[] args) {
int a = 4;
try {
System.out.println(a/0);
} catch (ArithmeticException e) {
System.out.println("Произошла недопустимая арифметическая операция");
}
}
}
Операторы программы, которые вы хотите отслеживать, помещаются в блок try. Если
исключение произошло, то оно создаётся и передаётся дальше. Ваш код может
перехватить исключение при помощи блока catch и обработать его.
try{
//здесь код, который потенциально может привести к ошибке
}
catch(SomeException e ){ //в скобках указывается класс конкретной ожидаемой ошибки
//здесь описываются действия, направленные на обработку исключений
}
finally{
//код, который нужно выполнить после завершения блока try
//выполняется в любом случае ( блок finnaly не обязателен)
}
Блок catch должен всегда связываться с блоком try и не может существовать
самостоятельно.

6.

Одному try может соответствовать сразу несколько
блоков catch с разными классами исключений.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
int[] m = {-1,0,1};
Scanner sc = new Scanner(System.in);
try {
int a = sc.nextInt();
m[a] = 4/a;
System.out.println(m[a]);
} catch (ArithmeticException e) {
System.out.println("Произошла недопустимая арифметическая
операция");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Обращение по недопустимому индексу массива");
}
}
}

7.

Следует помнить что!
При использовании множественных операторов catch обработчики подклассов
исключений должные находиться выше, чем обработчики их суперклассов.
Иначе, суперкласс будет перехватывать все исключения, имея большую область
перехвата.
Иными словами, Exception не должен находиться выше ArithmeticException и
ArrayIndexOutOfBoundsException.
} catch (Exception e) {
System.out.println("Произошло ещё какое-то исключение");
}
Если обработка ошибок не отличается то существует конструкция, с помощью
которой можно пере отлавливать несколько исключений одни блоком catch:
try {
...
} catch( IOException | SQLException ex ) {
System.out.println(«Error message:» + ex.getMessage());
}

8.

Оператор throw
Mожно , бросить собственные исключения при помощи оператора throw который
порождает исключение .
if (text == null || word == null) {
throw new NullPointerException("text == null || word == null");
}
Поток выполнения останавливается непосредственно после оператора throw и
другие операторы не выполняются. При этом ищется ближайший блок try/catch
соответствующего исключению типа.

9.

Когда же нужно бросать ошибки?
Чаще всего Exceptions бросаются при нарушении контракта метода.
Контракт (contract) - это негласное соглашение между создателем метода
(метод сделает и/или вернет именно то, что надо) и пользователем метода
(на вход метода будут передаваться значения из множества допустимых).
Пользователь метода может нарушить контракт, например, таким
способом: на вход Integer.parseInt(String) подать строку с буквами и по
заслугам получить NumberFormatException.
public Contract getContractById(String id) {
if (id == null) throw new NullPointerException("id is null");
...
}
Когда мы бросаем ошибку то помогаем вызывающей стороне понять,
что они нарушают контракт метода, причиной чего часто может быть ошибка
в логике их же приложения.

10.

Оператор throws
Если метод может породить исключение, которое он сам не обрабатывает, он должен
задать это поведение так, чтобы вызывающий его код мог позаботиться об этом исключении.
Для этого к объявлению метода добавляется конструкция throws, которая перечисляет
типы исключений. Общая форма объявления метода с оператором throws:
public int[] findWord(String text, String word) throws NullPointerException {
if (text == null || word == null) {
throw new NullPointerException("text == null || word == null");
}
int[] massivRez = new int[text.length()];
int indexOf = 0;
int i = 0;
int fromIndex = 0;
while (indexOf < text.length() && indexOf != -1) {
indexOf = text.indexOf(word, fromIndex);
if (indexOf >= 0) {
massivRez[i++] = indexOf;
fromIndex = indexOf += word.length();
}
}
int[] massivRez2 = new int[i];
for (int j = 0; j < i; j++) {
massivRez2[j] = massivRez[j];
}
return massivRez2;
}

11.

Список не проверяемых системных исключений
ArithmeticException - арифметическая ошибка, например, деление на нуль
ArrayIndexOutOfBoundsException - выход индекса за границу массива
ArrayStoreException - присваивание элементу массива объекта несовместимого
типа
ClassCastException - неверное приведение
EnumConstantNotPresentException - попытка использования неопределённого
значения перечисления
IllegalArgumentException - неверный аргумент при вызове метода
IllegalMonitorStateException - неверная операция мониторинга
IllegalStateException - некорректное состояние приложения
IllegalThreadStateException - запрашиваемая операция несовместима с текущим
потоком
IndexOutofBoundsException - тип индекса вышел за допустимые пределы
NegativeArraySizeException - создан массив отрицательного размера
NullPointerException - неверное использование пустой ссылки
NumberFormatException - неверное преобразование строки в числовой формат
SecurityException - попытка нарушения безопасности
StringIndexOutOfBounds - попытка использования индекса за пределами строки
TypeNotPresentException - тип не найден
UnsupportedOperationException - обнаружена неподдерживаемая операция

12.

Создание своих классов исключений
Для обработки собственных исключений , специфичных для ваших
приложений, можно создавать собственные классы исключений.
Это достаточно просто сделать: просто определите подкласс Exception. Ваши
подклассы исключений не обязаны реализовывать что-либо — важно само их
присутствие в системе типов, которое позволит использовать их как исключения.
class MyException extends Exception {
private int detail;
public MyException(int a) {
detail = a;
}
public String toString() {
return "MyException[" + detail +"]";
}
}

13.

public class ExceptionDemo {
static void compute(int a) throws MyException {
System.out.println("Вызван compute(" + a + ")");
if(a > 10) throw new MyException(a);
System.out.println("Нормальное завершение");
}
public static void main(String args[]) {
try {
compute(1);
compute(20);
}catch (MyException e) {
System.out.println("Перехвачено " + e) ;
}
}
}

14.

Mетоды класса Throwable
final void addSuppressed(Throwable exception) - добавляет исключение в список
подавляемых исключений (JDK 7)
Throwable fillInStackTrace() - возвращает объект класса Throwable, содержащий
полную трассировку стека.
Throwable getCause() - возвращает исключение, лежащее под текущим исключение
или null
String getLocalizedMessage() - возвращает локализованное описание исключения
StackTraceElement[] getStackTrace() - возвращает массив, содержащий трассировку
стека и состояний из элементов класса StackTraceElement
final Throwable[] getSuppressed() - получает подавленные исключения (JDK 7)
Throwable initCause(Throwable exception) - ассоциирует исключение с вызывающим
исключением. Возвращает ссылку на исключение.
void printStackTrace() - печатает stack trace, который содержит информацию, с
помощью которой можно определить причину исключения и место, где оно было
брошено.
void printStackTrace(PrintWriter stream) - посылает трассировку стека в заданный поток
void setStackTrace(StackTraceElement elements[]) - устанавливает трассировку стека
для элементов (для специализированных приложений)
String toString() - возвращает название класса и текст ошибки
String getMessage() - возвращает текст ошибки
* - для вывода ошибок можно использовать отдельный поток (System.err).
English     Русский Правила