JavaRush /Курсы /Java Syntax /Как работает множественный catch

Как работает множественный catch

Java Syntax
9 уровень , 7 лекция
Открыта
Как работает множественный catch - 1

— И ещё немного интересных уроков. Мне так нравится преподавать.

— Хочу рассказать тебе, как работает множественный catch. Все очень просто: при возникновении исключения в блоке try, выполнение программы передаётся на первый catch.

— Если тип, указанный внутри круглых скобок блока catch, совпадает с типом объекта-исключения, то начинается выполнение кода внутри блока {}. Иначе переходим к следующему catch. Там проверка повторяется.

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

— Ясно. Будет выполнен тот catch, тип в котором совпадает с типом исключения.

— Да, верно. Но в реальности все немного сложнее. Дело в том, что классы можно наследовать друг от друга. И если класс «Корова» унаследовать от класса «Животное», то объект типа «Корова» можно хранить не только в переменной типа «Корова», но и в переменной типа «Животное».

— И?

— Т.к. все исключения унаследованы от классов Exception или RuntimeException (который тоже унаследован от Exception), то их все можно перехватить командами catch (Exception e) или catch (RuntimeException e).

— И?

— Отсюда два вывода. Во-первых, с помощью команды catch(Exception e) можно перехватить любое исключение вообще. Во-вторых — порядок блоков catch имеет значение.

Примеры:

— Возникший при делении на 0 ArithmeticException будет перехвачен во втором catch.

Код
try
{
    System.out.println("Before method1 calling.");
    int a = 1 / 0;
    System.out.println("After method1 calling. Never will be shown.");
}
catch (NullPointerException e)
{
    System.out.println("Reference is null. Exception has been caught.");
}
catch (ArithmeticException e)
{
    System.out.println("Division by zero. Exception has been caught.");
}
catch (Exception e)
{
    System.out.println("Any other errors. Exception has been caught.");
}

— В примере ниже возникший ArithmeticException будет перехвачен в первом catch, т.к. классы всех исключений унаследованы от Exception. Т.е. Exception захватывает любое исключение.

Код
try
{
    System.out.println("Before method1 calling.");
    int a = 1/0;
    System.out.println("After method1 calling. Never will be shown.");
}
catch (Exception e)
{
    System.out.println("Any other errors. Exception has been caught.");
}
catch (NullPointerException e)
{
    System.out.println("Reference is null. Exception has been caught.");
}
catch (ArithmeticException e)
{
    System.out.println("Divided by zero. Exception has been caught.");
}

— В примере ниже исключение ArithmeticException не будет перехвачено, а будет выброшено дальше в вызывающий метод.

Код
try
{
    System.out.println("Before method1 calling.");
    int a = 1/0;
    System.out.println("After method1 calling. Never will be shown.");
}
catch (NullPointerException e)
{
    System.out.println("Reference is null. Exception has been caught.");
}

— Ну, вроде все понемногу проясняется. Непростая штука эти исключения.

— Это только кажется так. На самом деле – это чуть ли не самая простая вещь в Java.

— Не знаю, радоваться по этому поводу или огорчаться…

9
Задача
Java Syntax Pro, 9 уровень, 7 лекция
Недоступна
Логические операторы
Внеси исправления в метод taskForCondition(), чтобы он выводил в консоли число 30. Изменять можно только логические операторы: && на & и || на |.
9
Задача
Java Syntax Pro, 9 уровень, 7 лекция
Недоступна
Приоритеты
Внеси исправления в метод main(), чтобы он выводил в консоли число 12.
9
Задача
Java Syntax Pro, 9 уровень, 7 лекция
Недоступна
Инкременты
Внеси исправления в метод main(), чтобы он выводил в консоли число 20. В методе можно изменять только постинкремент на преинкремент и наоборот, а также постдекремент на предекремент и наоборот.
Комментарии (175)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Alexey Shtamov Уровень 38
4 октября 2022
Сама работа с исключениями мне понятна, но как это применяется на реальной практике? Типо, мы может поймать ошибку, сделать с ней что-то, чтобы программа могла продолжить свою работу, я так понимаю?
4 ноября 2022
Тебе очень много придется с этим работать, поверь. Программирование - это вам не сортировка пузырьками и другие алгоритмы, это работа с неадекватностью пользователей и данных на входе)) если кратко
Евгений N Уровень 23
20 апреля 2022
господа! может с какой-то версии обработка стала другой? это код (предпоследний пример из лекции выше) падает при выполнении и в вебе и у меня в idea

 В примере ниже возникший ArithmeticException будет перехвачен в первом catch, т.к. классы всех исключений унаследованы от Exception. Т.е. Exception захватывает любое исключение.
try {
    System.out.println("Before method1 calling.");
    int a = 1/0;
    System.out.println("After method1 calling. Never will be shown.");
}
catch (Exception e)
{     System.out.println("Any other errors. Exception has been caught.");
}
catch (ArithmeticException e)
{     System.out.println("Divided by zero. Exception has been caught.");
}
с ошибкой ArithmeticException has already been caught но если catch (Exception e) переставить в конец - то всё ок. т.е. компилятор хочет чтобы мы расставляли ошибки по иерархии, общие - в конце.
Павел Соловьёв Уровень 16
17 июня 2022
уровень 9 лекция 3 — Все исключения – это классы, унаследованные от класса Exception. Мы можем перехватить любое из них, указав в блоке catch его класс, или все сразу, указав общий родительский класс — Exception. Затем из переменной e (эта переменная хранит ссылку на объект исключения), можно получить всю необходимую информацию о возникшей ошибке. — Круто! А если в моем методе могут возникнуть разные исключения, можно обрабатывать их по-разному? — Не можно, а нужно. Сделать это можно вот так:... Кажется ответ скрыт в этом диалоге .
Евгений N Уровень 23
17 июня 2022
😁 в общем мне не понравилось, что пример из лекции падает с ошибкой. но может быть это специально, чтобы студенты лучше поняли материал.
Nikita Prokaev Уровень 23
14 июля 2022
Здесь еще смысл в том, что не имеют смысла дальнейшие catch после catch(Exception e), так как если исключение не перехватилось на вершине иерархии, то оно уже нигде не перехватится. так что весь код ниже - лишний. P.S. Скорее всего эта информация уже не актуальна, но может новеньким пригодится)
Grock Уровень 44
14 сентября 2022
Из текущей лекции: — Отсюда два вывода. Во-первых, с помощью команды catch(Exception e) можно перехватить любое исключение вообще. Во-вторых — порядок блоков catch имеет значение. ... — В примере ниже возникший ArithmeticException будет перехвачен в первом catch, т.к. классы всех исключений унаследованы от Exception. Т.е. Exception захватывает любое исключение.
Aleksei Reinsalu Уровень 19
20 ноября 2021
На моем уровне понимания, в последнем примере программа вообще может упасть, если в названии метода забыли указать, что он бросает ошибки которые отличаются от NPE
Тимур Уровень 22
15 марта 2021
не понял только эту строчку: " Если блоки catch закончились, а исключение так и не было перехвачено, то оно выбрасывается дальше, а текущий метод аварийно завершается."
16 марта 2021
Ну у тебя код не скомпилируется(исключение не будет перехвачено) и выдаст ошибку
Расул Уровень 23
9 апреля 2021
Это значит, что если при возникновении исключения в коде в try и при отсутствии блока catch, исключение , в поисках catch будет "проталкиваться" все дальше и дальше. И если не найдется этот блок, то метод завершится, да и весь код тоже, в случае отсутствия try/catch.
Serzhes Уровень 20
26 мая 2021
Это значит, что возникший в коде проги тип исключения не совпадает с типами исключений, которые перехватывают/обрабатывают написанные блоки catch. Все равно, что не писать try/catch.
hidden #2436024 Уровень 14
17 января 2021
Неплохая по восприятию лекция,но по-моему все как-то тривиально,не правда ли? Можно эту инфу отдельно не выделять было? Хотя авторам виднее и спасибо им за их труд!
Aleksandra Уровень 12
20 декабря 2020
А есть ли разница как перехватывать исключение с помощью catch (Exception e) или catch (тип исключения e)? Ведь и так и так исключение будет перехвачено...
Константин Уровень 23
20 декабря 2020
Думаю разница в том как ты будешь обрабатывать эти исключения. Т.е. для разных типов исключений в одном методе у тебя может быть несколько последующих действий, а если ты будешь ловить все исключения с помощью Exception e , то можешь написать только один вариант обработки.
4 ноября 2022
Не совсем верно. Можно перехватить один раз с помощью Exception e и в этом блоке проверять тип ошибки, например e.getClass или e instance of .. .Но как вы уже догадались, это моветон)
Виталий Гнутов Уровень 19
24 ноября 2020
Самое время узнать, как это будет на паскале!
7 января 2021
там все также. try ... except
VladimirPic Уровень 38
2 ноября 2021
Тонко
PERFORATTOR Уровень 19
27 января 2022
Убрали что ль
Никита Уровень 10
9 ноября 2020
Образное Объяснение (стек вызовов + выброс исключения): Представьте себе, что открывая браузер, вы сами запускаетесь как программа: в стеке вызовов под вас обработчик выделяет новый блок памяти. Начинаете с метода main (например у вас на стартовой странице портал mail.ru) Для обработки каждой вкладки вашему ИИ требуется запускать отдельный метод: 1-метод: читаете анонс статьи, потом переходите по ссылке в другую вкладку; 2 метод: там читаете статью, вас что-то заинтересовывает, и в новой вкладке вы вбиваете новый запрос; 3 метод: смотрите видео по теме - третья вкладка; 4 метод: узнаете о новом интересном блогере и переходите на его канал - четвёртая; 5 метод: видите что у него в дружественных каналах есть интересная тема; 6 метод: переходите и запускаете приветственное видео в следующей вкладке; 7 метод: видите в рекомендациях видео по теме, которая давно вас интересовала. Переходите по ссылке и смотрите; .... И так с каждой открытой вкладкой (или точнее с каждым вызванным методом) ваш стек растёт.
Anonymous #2297535 Уровень 22
31 декабря 2020
аналогии это хорошо, но иногда они могут сыграть злую шутку
Никита Уровень 10
9 ноября 2020
В какой-то момент вы понимаете, что из всего этого надо выбираться. Вы не можете сразу попасть в первый метод, вам сначала нужно завершить текущий (то есть досмотреть видео). Вы его досматриваете (или проматываете вылавливая только суть), и дальше закрываете вкладку. Вот тут метод 7 завершается и вы возвращаетесь в ---> метод 6 - быстро просматриваете страницу и закрываете шестую вкладку и возвращаетесь в ---> метод 5 .... и так далее закрывая вкладки вы попадаете во все методы завершая гештальты каждый метод по очереди. Четвертый, третий, второй, первый и наконец вы возвращаетесь в main - это страница с которой всё началось (портал mail.ru). Вы выдыхаете и закрываете браузер. Всё, ваша программа завершилась. Вот примерно так работает стек вызовов. И если например в 6-м методе вы увидели нечто такое, что выбило вас из колеи и метод завершается аварийно, процесс возврата всё равно пройдет по всему стеку в самый низ, до метода main (чтобы собрать полный стек вызовов и вывести StackTrace в консоль). Так вот, чтобы такого не случилось, и программа не вылетала обратно на mail.ru с потерей всех данных, мы и перехватываем исключение прямо в том методе в котором оно возникло. В итоге программа аварийно вылетит только из одного метода и спокойно продолжит работать со следующей строчки кода после той где был вызван этот "плохой" метод.
Никита Уровень 10
9 ноября 2020
P.S. Хорошая картинка, которая показывает как связаны стек(STACK) и куча(HEAP). В стеке находятся ссылки на объекты и примитивные значения (типа int). Остальное (более объёмные) данные расположены в куче (область памяти с неструктурированными данными, которые обнаруживаются инструкцией только по ссылке из стека).
Luk_d Уровень 39
9 ноября 2020
Второй пример даже не скомпилируется
ASY Уровень 17
3 февраля 2021
Не все об этом знают....
11 июля 2021
А почему он не скомпилируется?