try + catch
исключение перехвачено точным перехватчиком
>> 0
>> 1
>> 2
исключение перехвачено точным-перехватчиком среди множества перехватчиков
исключение не перехвачено единственным перехватчиком
исключение не перехвачено множеством перехватчиком
исключение перехвачено ПЕРВЫМ подходящим перехватчиком из множества подходящих
ошибка компиляции: перехватчик предка стоит перед перехватчиком потомка
из одного catch не попадешь в другой catch -> новое исключение летит "выше"
можно повторно бросить перехваченное исключение -> повторно брошенное исключение летит "выше" (рекурсии не возникает - повторного входа в тот же самый catch)
в finally заходим всегда, состояние летящего исключения приостанавливается но не очищается
>> 0
>> 1
>> 24
>> 0
>> 1
>> 5
Далее следует хорошо различать две ситуации
- этого нельзя/можно сделать (вопросы синтаксиса)
- этого не рекомендуется делать (вопросы семантики)
Примеры
1) Что произойдет при запуске этого кода?
2) Если вы для трассировки вставите System.out.println(..) - это повлияет на работу примера. Как?
Факты
1. В Java 5 ключевых слов для работы с исключениями: try, catch, finally, throw, throws.
2. Исключение - способ узнать имя метода и номер строки (так делают Log4j).
3. В секцию finally попадаем всегда. За исключением
- System.exit(...)
- Runtime.getRuntime().halt(...);
- Runtime.getRuntime().exit(...);
4. любому методу в сигнатуру можно добавить throws AnyException, хоть чек/унчек вне зависимости от тела.
5. чек/унчек влияет только на компиляцию, перехватываются все одинаково можно
6. я могу напрямую наследоваться от Throwable, хотя так и не принято
7. У исключений могут быть поля и методы
8. у исключения может быть message + clause
9. исключение это способ вернуть Разные резльтаты из одной сигнатуры
10. в java 7 добавилось
- Multi-catch exceptions, which we cover here
- try-with-resources
11. throw и new - независимые инструкции (в какой момент наполняется стектрейс?).
- в каком случае я МОГУ добавить в сигнатуру throws RE?
- в каком случае я НЕ МОГУ добавить в сигнатуру throws RE?
- в каком случае я ОБЯЗАН добавить в сигнатуру throws RE?
- в каком случае я МОГУ добавить в сигнатуру throws Ex?
- в каком случае я НЕ МОГУ добавить в сигнатуру throws Ex?
- в каком случае я ОБЯЗАН добавить в сигнатуру throws Ex?
- я не зайду в finally если
- не было исключения
- return;
- throw new - не перехваченный catch
- throw new - перехваченный catch
- throw new - перехваченный catch и catch кинул новое
- System.exit
- Runtime.exit
- Runtime.halt
- я могу наследоваться исключительно от нефинальных Ex и RuEx или их потомков.
- да, Er и Th - нельзя наследоваться
- могу еще и от Er
- могу еще и от Th
- могу еще и от Er и от Th
- мы не можем обернуть чекед в анчекед (да, нет)
- последовательность catch
- er, ex, re, остальные
- er, er-насл, ex, ex-насл, re, re-насл
- нельзя ставить предка выше потомка, в остальном произвольно
- Throwable можно перехватывать (да, нет, можно но не рекомендуется)
- Error можно перехватывать (да, нет, можно но не рекомендуется)
- Exception можно перехватывать (да, нет, можно но не рекомендуется)
- RuntimeException можно перехватывать (да, нет, можно но не рекомендуется)
- неперехваченное исключение
- убивает поток
- убивает приложение
- попадает в DefaultExceptionHandler
Лабораторные
ex.mech.Simple
Задания лабораторных можно прочитать на этой странице.
исключение перехвачено точным перехватчиком
class ExceptionTest_TC_0 {
public static void main(String[] args) {
try {
System.out.println(0);
throw new RuntimeException();
} catch (RuntimeException e) {
System.out.println(1);
}
System.out.println(2);
}
}
>> 0
>> 1
>> 2
исключение перехвачено перехватчиком предка
class ExceptionTest_TC_1 {
public static void main(String[] args) {
try {
System.out.println(0);
throw new RuntimeException();
} catch (Exception e) {
System.out.println(1);
}
System.out.println(2);
}
}
>> 1
>> 2
исключение перехвачено точным-перехватчиком среди множества перехватчиков
class ExceptionTest_TC_2 {
public static void main(String[] args) {
try {
System.out.println(0);
throw new RuntimeException();
} catch (NullPointerException e) {
System.out.println(1);
} catch (RuntimeException e) {
System.out.println(2);
} catch (Exception e) {
System.out.println(3);
}
System.out.println(4);
}
}
>> 0
>> 2
>> 4
исключение перехвачено перехватчиком предка среди множества перехватчиков>> 2
>> 4
class ExceptionTest_TC_3 {
public static void main(String[] args) {
try {
System.out.println(0);
throw new RuntimeException();
} catch (NullPointerException e) {
System.out.println(1);
} catch (Exception e) {
System.out.println(2);
} catch (Error e) {
System.out.println(3);
}
System.out.println(4);
}
}
>> 0
>> 2
>> 4
class ExceptionTest_TC_4 {
public static void main(String[] args) {
try {
System.out.println(0);
throw new RuntimeException();
} catch (NullPointerException e) {
System.out.println(1);
}
System.out.println(2);
}
}
>> 0
>> RuntimeException ...исключение не перехвачено множеством перехватчиком
class ExceptionTest_TC_5 {
public static void main(String[] args) {
try {
System.out.println(0);
throw new RuntimeException();
} catch (NullPointerException e) {
System.out.println(1);
} catch (ArithmeticException e) {
System.out.println(2);
}
System.out.println(3);
}
}
>> 0
>> RuntimeException ...
class ExceptionTest_TC_6 {
public static void main(String[] args) {
try {
System.out.println(0);
throw new NullPointerException();
} catch (ArithmeticException e) {
System.out.println(1);
} catch (RuntimeException e) {
System.out.println(2);
} catch (Exception e) {
System.out.println(3);
}
System.out.println(4);
}
}
>> 0
>> 2
>> 4
class ExceptionTest_TC_7 {
public static void main(String[] args) {
try {
System.out.println(0);
throw new NullPointerException();
} catch (ArithmeticException e) {
System.out.println(1);
} catch (Exception e) {
System.out.println(3);
} catch (RuntimeException e) {
System.out.println(2);
}
System.out.println(4);
}
}
class ExceptionTest_TC_8 {
public static void main(String[] args) {
try {
System.out.println(0);
throw new NullPointerException();
} catch (NullPointerException e) {
System.out.println(1);
throw new ArithmeticException();
} catch (ArithmeticException e) {
System.out.println(2);
}
System.out.println(5);
}
}
>> 0
>> 1
>> ArithmeticException ...class ExceptionTest_TC_9 {
public static void main(String[] args) {
try {
System.out.println(0);
throw new NullPointerException();
} catch (NullPointerException e) {
System.out.println(1);
throw e;
} catch (ArithmeticException e) {
System.out.println(2);
}
System.out.println(5);
}
}
>> 0
>> 1
>> NullPointerException ...
try + finally
class ExceptionTest_TF_0 {
public static void main(String[] args) {
System.out.println(f());
}
public static int f() {
try {
System.out.println(0);
throw new RuntimeException();
} finally {
System.out.println(1);
}
}
}
>> 0
>> 1
>> RuntimeException ...
в finally заходим всегда, состояние возврата return приостанавливается но не очищается
class ExceptionTest_TF_1 {
public static void main(String[] args) {
System.out.println(f());
}
public static int f() {
try {
System.out.println(0);
return 42;
} finally {
System.out.println(1);
}
}
}
>> 0
>> 1
>> 42
>> 1
>> 42
в finally заходим всегда, return в finally переписывает return из try
class ExceptionTest_TF_2 {
public static void main(String[] args) {
System.out.println(f());
}
public static int f() {
try {
System.out.println(0);
return 42;
} finally {
System.out.println(1);
return 24;
}
}
}
>> 0
>> 1
>> 24
>> 1
>> 24
в finally заходим всегда, return в finally переписывает исключение из try
class ExceptionTest_TF_3 {
public static void main(String[] args) {
System.out.println(f());
}
public static int f() {
try {
System.out.println(0);
throw new RuntimeException();
} finally {
System.out.println(1);
return 24;
}
}
}
>> 0
>> 1
>> 24
в finally заходим всегда, исключение в finally переписывает return из try
class ExceptionTest_TF_4 {
public static void main(String[] args) {
System.out.println(f());
}
public static int f() {
try {
System.out.println(0);
return 42;
} finally {
System.out.println(1);
throw new RuntimeException();
}
}
}
>> 0
>> 1
>> RuntimeException ...
>> 1
>> RuntimeException ...
в finally заходим всегда, исключение в finally переписывает исключение из try
class ExceptionTest_TF_5 {
public static void main(String[] args) {
System.out.println(f());
}
public static int f() {
try {
System.out.println(0);
throw new RuntimeException();
} finally {
System.out.println(1);
throw new NullPointerException();
}
}
}
>> 0
>> 1
>> NullPointerException ...
try + catch + finally
Исключение перехвачено точным перехватчиком
class ExceptionTest_TCF_1A {
public static void main(String[] args) {
try {
System.out.println(0);
if (true) {
throw new NullPointerException();
}
} catch (NullPointerException e) {
System.out.println(1);
} finally {
System.out.println(5);
}
System.out.println(6);
}
}
>> 0
>> 1
>> 5
>> 6
>> 1
>> 5
>> 6
Исключение перехвачено перехватчиком предка
class ExceptionTest_TCF_1B {
public static void main(String[] args) {
try {
System.out.println(0);
if (true) {
throw new NullPointerException();
}
} catch (RuntimeException e) {
System.out.println(1);
} finally {
System.out.println(5);
}
System.out.println(6);
}
}
>> 0
>> 1
>> 5
>> 6
Исключение не перехвачено
class ExceptionTest_TCF_1C {
public static void main(String[] args) {
try {
System.out.println(0);
if (true) {
throw new RuntimeException();
}
} catch (NullPointerException e) {
System.out.println(1);
} finally {
System.out.println(5);
}
System.out.println(6);
}
}
>> 0
>> 5
>> RuntimeException
Исключение перехвачено, но в catch-блоке инициировано другое исключение
class ExceptionTest_TCF_10A {
public static void main(String[] args) {
try {
System.out.println(0);
if (true) {
throw new NullPointerException();
}
} catch (NullPointerException e) {
System.out.println(1);
throw new IllegalArgumentException();
} finally {
System.out.println(5);
}
System.out.println(6);
}
}
>> 0
>> 1
>> 5
>> IllegalArgumentException
Исключение перехвачено, но finally-блок выкинул исключение
class ExceptionTest_TCF_10B {
public static void main(String[] args) {
try {
System.out.println(0);
if (true) {
throw new NullPointerException();
}
} catch (NullPointerException e) {
System.out.println(1);
} finally {
System.out.println(5);
if (true) {
throw new IllegalArgumentException();
}
}
System.out.println(6);
}
}
>> 0
>> 1
>> 5
>> IllegalArgumentException
?
?
>> ?
?
?
>> ?
Из одного catch-блока не попадаем во второй
class ExceptionTest_TCF_20 {
public static void main(String[] args) {
try {
System.out.println(0);
throw new NullPointerException();
} catch (NullPointerException e) {
System.out.println(1);
throw new IllegalArgumentException();
} catch (IllegalArgumentException e) {
System.out.println(2);
} finally {
System.out.println(5);
}
System.out.println(6);
}
}
>> 0
>> 1
>> 5
>> IllegalArgumentExceptionДалее следует хорошо различать две ситуации
- этого нельзя/можно сделать (вопросы синтаксиса)
- этого не рекомендуется делать (вопросы семантики)
Примеры
public class DeepDiveException {
public static void main(String[] args) {
f();
}
public static void f() {
try {
f();
} catch (StackOverflowError e) {
f();
} finally {
f();
}
}
}
1) Что произойдет при запуске этого кода?
2) Если вы для трассировки вставите System.out.println(..) - это повлияет на работу примера. Как?
Факты
1. В Java 5 ключевых слов для работы с исключениями: try, catch, finally, throw, throws.
2. Исключение - способ узнать имя метода и номер строки (так делают Log4j).
3. В секцию finally попадаем всегда. За исключением
- System.exit(...)
- Runtime.getRuntime().halt(...);
- Runtime.getRuntime().exit(...);
4. любому методу в сигнатуру можно добавить throws AnyException, хоть чек/унчек вне зависимости от тела.
5. чек/унчек влияет только на компиляцию, перехватываются все одинаково можно
6. я могу напрямую наследоваться от Throwable, хотя так и не принято
7. У исключений могут быть поля и методы
8. у исключения может быть message + clause
9. исключение это способ вернуть Разные резльтаты из одной сигнатуры
10. в java 7 добавилось
- Multi-catch exceptions, which we cover here
- try-with-resources
11. throw и new - независимые инструкции (в какой момент наполняется стектрейс?).
- в каком случае я МОГУ добавить в сигнатуру throws RE?
- в каком случае я НЕ МОГУ добавить в сигнатуру throws RE?
- в каком случае я ОБЯЗАН добавить в сигнатуру throws RE?
- в каком случае я МОГУ добавить в сигнатуру throws Ex?
- в каком случае я НЕ МОГУ добавить в сигнатуру throws Ex?
- в каком случае я ОБЯЗАН добавить в сигнатуру throws Ex?
- я не зайду в finally если
- не было исключения
- return;
- throw new - не перехваченный catch
- throw new - перехваченный catch
- throw new - перехваченный catch и catch кинул новое
- System.exit
- Runtime.exit
- Runtime.halt
- я могу наследоваться исключительно от нефинальных Ex и RuEx или их потомков.
- да, Er и Th - нельзя наследоваться
- могу еще и от Er
- могу еще и от Th
- могу еще и от Er и от Th
- мы не можем обернуть чекед в анчекед (да, нет)
- последовательность catch
- er, ex, re, остальные
- er, er-насл, ex, ex-насл, re, re-насл
- нельзя ставить предка выше потомка, в остальном произвольно
- Throwable можно перехватывать (да, нет, можно но не рекомендуется)
- Error можно перехватывать (да, нет, можно но не рекомендуется)
- Exception можно перехватывать (да, нет, можно но не рекомендуется)
- RuntimeException можно перехватывать (да, нет, можно но не рекомендуется)
- неперехваченное исключение
- убивает поток
- убивает приложение
- попадает в DefaultExceptionHandler
Лабораторные
ex.mech.Simple
ex.mech.MultiCatch
ex.mech.InfOrNotInfЗадания лабораторных можно прочитать на этой странице.