827.72K
Category: programmingprogramming

Java Basic. Исключения

1.

Java Basic
Исключения
otus.ru

2.

Проверяем что идет запись
Напишите «+» в чат, если меня
слышно и видно

3.

Тема вебинара
Исключения
Романов Александр
Тимлид в Tinkoff
Автор телеграм-канала AlexProIT

4.

Маршрут вебинара
1. Исключения
2. Рефлексия

5.

Цель вебинара
● Изучить обработку ошибок в языке Java

6.

Что такое исключения
Исключения в Java представляют собой объекты, генерируемые во время
появления ошибочных ситуаций и содержащие информацию о них. В зависимости
от типа ошибки, будет меняться и класс генерируемого исключения.
Тип исключения
Описание
ArithmeticException
Арифметическая ошибка
ArrayIndexOutOfВoundsException
Выход индекса за пределы массива
ClassCastException
Неверное приведение типов
IllegalArgumentException
Употребление недопустимого аргумента при вызове метода
IndexOutOfВoundsException
Выход индекса некоторого типа за допустимые пределы
NullPointerException
Неверное использование пустой ссылки
NumberFormatException
Неверное преобразование символьной строки в числовой формат

7.

Пример ошибочной ситуации
package ru.otus.exceptions;
public class MainApplication {
public static void main(String[] args) {
int a = 0;
int b = 10 / a;
}
}
Результат выполнения:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at ru.otus.exceptions.MainApplication.main(MainApplication.java:6)

8.

Что означает вывод в консоль?
1 package ru.otus.exceptions;
2
3 public class MainApplication {
4
public static void doSomething() {
5
int a = 0;
6
int b = 10 / a;
7
}
8
9
public static void main(String[] args) {
10
doSomething();
11
}
12 }
Результат выполнения:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at ru.otus.exceptions.MainApplication.doSomething(MainApplication.java:6)
at ru.otus.exceptions.MainApplication.doSomething(MainApplication.java:10)
При появлении ошибки в консоли печатается:
Имя потока, в котором возникло исключение (к этому вернемся на теме многопоточности)
Распечатка стека вызовов методов, показывающая цепочку вызовов методов, которая привела к появлению исключения
Класс, метод и номер строки, в которой непосредственно возникло исключение
Класс исключения (ArithmeticException), указывающая на причину возникновения ошибки

9.

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

10.

Деление исключений на группы
● Класс Exception и его подклассы
● Класс RuntimeException и его подклассы
● Класс Error и его подклассы

11.

Зачем перехватывать исключения?
public static void main(String[] args) {
int a, b;
a = 0;
b = 10 / a;
System.out.println("Это сообщение не будет выведено в консоль");
}
При делении на ноль, Java сгенерирует и бросит исключение типа ArithmeticException. Если его не
перехватить, оно долетит до стандартного обработчика исключений Java, и работа приложения
завершится, а в консоль будет выведена информация об исключении (как было видно на одном из
прошлый слайдов).

12.

Перехват исключения через try-catch
public static void main(String[] args) {
int a, b;
try {
a = 0;
b = 10 / a;
System.out.println("Это сообщение не будет выведено в консоль");
} catch (ArithmeticException e) {
System.out.println("Ошибка деления на ноль");
}
System.out.println("Завершение работы");
}
Результат выполнения:
Деление на ноль
Завершение работы
В блоке try, в строке b = 10 / a; будет сгенерировано и брошено исключение, исполнение блока try
прервется, но мы перехватим его блоком catch, напечатаем “вручную” в консоль сообщение об ошибке, и
программа будет выполняться дальше (со строки, идущей после try-catch).

13.

Перехват исключения через try-catch с распечаткой
stack trace
public static void main(String args[]) {
System.out.println(1);
try {
int а = 0;
int b = 30 / а;
System.out.println(2);
} catch (ArithmeticException e) {
System.out.println(3);
e.printStackTrace();
}
System.out.println(4);
}
Результат выполнения:
1
3
java.lang.ArithmeticException: / by zero
at MainClass.main(MainClass.java:7)
4

14.

Несколько блоков catch
public static void main(String args[]) {
try {
int a = 0;
int b = 30 / a;
int[] с = { 1, 2, 3 };
с[42] = 10;
} catch (ArithmeticException е) {
System.out.println("Дeлeниe на ноль: " + е);
} catch (ArrayIndexOutOfBoundsException е){
System.out.println("Ошибка индексации массива: " + е);
}
System.out.println("Пocлe блока операторов try/catch");
}
Сгенерированное исключение будет последовательно проверяться блоками catch
сверху-вниз. Если один из catch сработал, то следующие блоки catch не задействуются.
Вопрос: Как думаете сработают ли здесь оба блока catch?

15.

Обработка нескольких исключений в одном
catch
public static void main(String args[]) {
try {
int a = 0;
int b = 30 / a;
int[] с = { 1, 2, 3 };
с[42] = 10;
} catch (ArithmeticException | ArrayIndexOutOfBoundsException е) {
System.out.println("Перехватили исключение");
}
System.out.println("Пocлe блока операторов try/catch");
}
Если реакция на несколько исключений одинакова, то можно воспользоваться объединением
типов исключений через |.

16.

Порядок блоков catch
public static void main(String args[]) {
try {
Неправильно
int а = 0;
int b = 30 / а;
} catch (Exception е) {
System.out.println("Exception");
} catch (ArithmeticException е) { // ошибка на этапе компиляции : недостижимый код!
System.out.println("Этот код недостижим");
}
}
При перехвате исключения определенного типа, мы перехватываем и исключения его
подтипов. Поэтому блоки catch с суперклассами, должны стоять ниже блоков catch с
их подклассами, в противном мы получим ошибку о недостижимом коде.

17.

Порядок блоков catch
public static void main(String args[]) {
try {
int а = 0;
int b = 30 / а;
} catch (ArithmeticException е) {
System.out.println("Этот код недостижим");
} catch (Exception е) {
System.out.println("Exception");
}
}
Правильно

18.

Checked и unchecked исключения
Все исключения делятся на два вида: checked и unchecked
Checked исключения должны быть обязательно обработаны через
блоки try-catch, либо проброшены наверх
Обработку unchecked исключений компилятор не отслеживает
Вид исключения, зависит от вида его родительского класса

19.

Обязательность/необязательность обработки
Если имеется код, который может привести к возникновению unchecked исключения, и который не
обернут в try-catch, то такую программу можно попробовать запустить и выполнить.
public static void main(String args[]) {
int а = 0;
int b = 30 / а;
int[] arr = new int[5];
arr[20] = 20;
}
Если же имеется код, который может привести к возникновению checked исключения, и который не
обернут в try-catch, то такую программу невозможно запустить и выполнить, так как будет получена
ошибка на этапе компиляции.
public static void main(String args[]) {
FileOutputStream out = new FileOutputStream("file.txt");
}

20.

Ручной бросок исключения
public double sqrt(double in) {
if (in < 0.0) {
throw new ArithmeticException("Невозможно вычислить корень
квадратный из отрицательного числа");
}
return Math.sqrt(in);
}
Если при работе наших методов, есть ситуации, при которых корректное выполнение метода
невозможно, то существует возможность вручную сгенерировать и бросить исключение

21.

Проброс исключения
public static void main(String args[]) {
try {
createReport();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void printResultToFile(String filename) throws IOException {
PrintWriter output = new PrintWriter(filename);
// ...
output.close();
}
Если в методе невозможно корректно обработать исключение, то его можно пробросить “наверх по
стеку” с помощью ключевого слова throws. И обработать выше по стеку. Обрабатывать выше по стеку
можно и unchecked исключения, для этого даже не требуется использовать ключевое слово throws.

22.

Оператор finally
try {
// блок кода, в котором отслеживаются исключения
} catch (ТипИсключения1 e) {
// обработчик исключения тип_исключения_1
} catch (ТипИсключения2 e) {
// обработчик исключения тип_исключения_2
} finally {
// блок кода, который обязательно выполнится по завершении блока try или catch
}
Блок finally срабатывает всегда, вне зависимости от того, было ли сгенерировано
или перехвачено исключение, или нет. Как правило, используется при работе с
“внешними” ресурсами.

23.

try-with-resources
public static void main(String[] args) throws Exception {
try (FileOutputStream out = new FileOutputStream("out.txt")) {
} catch (IOException e) {
}
}
В try-with-resources может быть передан только объект типа, реализующего
интерфейс Closeable

24.

Создание собственных типов
исключений
public class TransformException extends RuntimeException {
public TransformException(String message) {
super(message);
}
}
Чтобы класс стал исключением необходимо унаследовать его от класса
исключения
Тип (checked или unchecked) создаваемого исключения зависит от типа
родительского исключения. Чтобы создать checked исключения, надо
унаследоваться от checked исключения, для unchecked - от unchecked

25.

Создание собственных типов
исключений
Редко может требоваться добавлять исключениям дополнительные свойства.
public class TransformException extends RuntimeException {
private String format;
public String getFormat() {
return format;
}
public TransformException(String message, String format) {
super("Некорректный формат преобразования: " + format);
this.format = format;
}
}
Пример:
try {
// ...
} catch (TransformException e) {
System.out.println(e.getFormat());
}

26.

Рефлексия

27.

Цели вебинара
Проверка достижения целей
● Изучили обработку ошибок в языке Java

28.

Домашнее задание
Работа с исключениями
Цель домашнего задания: научиться работать с исключениями.
Реализуйте метод, аргументом которого является двумерный строковый массив размером 4х4. Если передан
массив другого размера необходимо бросить исключение AppArraySizeException.
Метод должен обойти все элементы массива, преобразовать в int и просуммировать. Если в каком-то элементе
массива преобразование не удалось (например, в ячейке лежит текст вместо числа), должно быть брошено
исключение AppArrayDataException с детализацией, в какой именно ячейке лежат неверные данные.
В методе main() необходимо вызвать полученный метод, обработать возможные исключения
AppArraySizeException и AppArrayDataException и вывести результат расчета (сумму элементов, при условии что
подали на вход корректный массив).
Заметка:
Для
преобразования
строки
Integer.parseInt(сюда_подать_строку);
к
числу
используйте
статический
метод
класса
Integer:
Заметка: Если Java не сможет преобразовать входную строку (в строке число криво написано), то будет сгенерировано
исключение NumberFormatException.

29.

Заполните, пожалуйста,
опрос о занятии
Спасибо за внимание!
English     Русский Rules