JavaRush /Курсы /Java Syntax Pro /Выбрасывание исключений

Выбрасывание исключений

Java Syntax Pro
14 уровень , 2 лекция
Открыта

1. Оператор throw

Исключение, пока оно не выброшено в систему, или когда оно уже перехвачено блоком catch — это в принципе просто объект класса, унаследованного от Exception (вернее, от Throwable). Никакими магическими особенностями сам объект-исключение не обладает.

Вся логика работы исключений — это просто особый сценарий поведения Java-машины, когда в ее среду выполнения вброшено исключение.

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

throw исключение;

Пример:

Код Вывод на экран
try
{
   int d = 2/0;
}
catch(Exception except)
{
   System.out.println("Перехватили исключение");
   throw except;
}
Перехватили исключение

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

Повторно выброшенное исключение не может быть захвачено другими блоками catch этого же try-блока.


2. Свое исключение

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

Это проще, чем кажется. Пример:

Код Вывод на экран
try
{
   throw new RuntimeException();
}
catch(Exception except)
{
   System.out.println("Перехватили исключение");
   throw except;
}
Перехватили исключение

В примере выше мы создали новый объект-исключение типа RuntimeException и тут же выбросили его с помощью оператора throw.

Оно будет сразу захвачено блоком catch, т.к. тип RuntimeException унаследован от типа Exception. Код catch(Exception except) захватывает объекты-исключения всех классов, унаследованных от класса Exception.



3. Ключевое слово finally

Еще один важный момент. Иногда программисту нужно сделать некоторые действия независимо от того, было исключение в коде или нет. Например, в коде мы открыли файл на запись, а открытый файл нужно обязательно закрыть вызовом метода close().

try
{
   код, где может возникнуть ошибка
}
catch(ТипИсключения имя)
{
   код обработки исключения
}
finally
{
   код, который нужно выполнить в любом случае
}

Для выполнения таких обязательных действий к оператору try-catch добавили еще один блок — finally, и получился оператор try-catch-finally. Выглядит это дело примерно так:

Пример:

FileInputStream source = null;
try
{
   source = new FileInputStream("c:\\note.txt");
   source.read();
}
catch(Exception except)
{
   System.out.println("Перехватили исключение");
   throw except;
}
finally
{
   if (source != null)
      source.close();
}

Код в блоке finally выполнится в любом случае независимо от того, было исключение или не было. Даже если исключение возникло, и оно не было перехвачено, блок finally все равно выполнится.

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

try
{
   код, где может возникнуть ошибка
}
finally
{
   код, который нужно выполнить в любом случае
}

Комментарии (249)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Anonymous #3585174 Уровень 33
8 июля 2025
like
Юрий Уровень 20
24 февраля 2025
try { Жили-были у деда; Гуси людоеды; catch(ExceptionEat e) { System.out.println(e); }
Andrey Ku Уровень 2 Expert
20 января 2025
Зачем нужно throw? Передача исключения дальше: Если программа не может обработать исключение полностью, оно передаётся на уровень вызова метода, чтобы обработка произошла выше по стеку вызовов. Прозрачность ошибок: Исключение остаётся доступным для других обработчиков. Например, если этот метод используется в другой части программы, вызывающий код узнает, что что-то пошло не так.
20 ноября 2024
Кото-то может подсказать по задаче со слоном, почему предыдущие ответы выводятся в консоли в обратном порядкем если снова выбросить искючение?
CodeMashine Уровень 33
20 ноября 2024
это ты сам реализовать должен. Сначала записать ответы куда нибудь , потом вывести в обратном порядке.
Олеся Уровень 18
5 декабря 2024
Это все из-за рекурсивного вызова функции (это когда функция вызывает саму себя). Обратный порядок вывода ответов связан с способом хранения цепочки вызовов функций в памяти компьютера. Когда одна функция вызывает внутри себя другую функцию, то контекст (ссылка на функцию, ее переменные) "верхней" функции сохраняется в стэк вызовов. Стэк - это структура хранения объектов, организованная по принципу LIFO. Last In - First Out. Последний пришел - первый вышел. Стэк можно представить себе как стопку тарелок. Тарелки кладутся на самый верх стопки и забираются с самого верха. Применительно к коду будет выглядеть так: если функция A вызывает функцию B, а B вызывает C, то в стеке будет сохранен контекст в последовательности A-> B-> C. В данном примере C - верх стека, самая верхняя тарелка. Когда функция C завершается, из стека достается контекст следующей функции B и продолжается выполнение функции B с того места, где ее выполнение было прервано вызовом C. После завершения B, соответственно выполняется функция A. В случае задачи со слоном функция buyElephant вызывает саму себя раз за разом до тех пор, пока вы не введете "ок". Каждый такой вызов кладется в стек и у каждого вызова сохраняется контекст ( переменная answer в том числе). Как только вы вводите "ок" выбрасывается исключение и текущая функция завершается. Исполнение переходит к функции ниже по стэку, в ней мы это исключение ловим в блоке catch и выводим переменную answer в консоль. Объект исключения пробрасывается дальше, функция завершается, из стека достается следующий контекст функции, снова ловим исключение в блок catch, выводим переменную в консоль и снова пробрасываем исключение для отлова во внешнюю функцию. И таким образом до самого дна стэка.
Anonymous #3513637 Уровень 25
9 декабря 2024
нет бро, это рекурсия
Anonymous #3438559 Уровень 4
24 декабря 2024
спасибо за отличное объяснение. прошу ответить на уточняющий вопрос, в коде два вызова метода buyElephant, первый из main - buyElephant(null, scanner);, а второй изнутри - buyElephant(answer, scanner);. для чего это сделано? первый вызов запускает рекурсию или они по очереди работают?
Victor Уровень 38
29 января 2025
Я думаю первый вызов с null - типа завязать разговор (аналогия - задание для переменной начального значения при объявлении, хотя дальше это значение может в программе вообще не появляться)
Виктор Уровень 24
28 июня 2025
Все́ понятно, спасибо.
Ринат Уровень 22
20 ноября 2024
Как я понял try-catch-throw-finally Если к примеру мы в коде не проработали какую то логику которая может привести к ошибке и программа по этому экстренно завершается. То надо бы, что ты наша программа не просто завершилась, но и "убиралась" за собой. Если программа контактирует с внешними ресурсами. закрыла открытые файлы, сохранила или наоборот не сохраняла изменения. Или сделала резервную копию. Там наверно еще много что надо бы обязательно сделать, но я пока этого не знаю.
w5277c Уровень 32
4 декабря 2024
Такие процессы, как закрытие файла при завершении программы - задача операционки. Именно она подчищает все ресурсы использованные программой, если программа сама этого не сделала.
Максим Антонов Уровень 27
3 ноября 2024
гайс а зачем нам вообще throw-ить ошибку? или например создавать зачем нам новую ошибку зачем например? не очень понимаю смысла в этих действиях, буду рад если кто нибуть пояснит заранее спасибо
Gralexx Уровень 19
13 ноября 2024
Согласен с вами! Из лекции не понятно зачем нам перехватывать исключение, чтобы потом опять его выбрасывать. Оператор throw, на мой взгляд новичка, объяснили ужасно.
Ринат Уровень 22
20 ноября 2024
Программа без try - catch^ Работает и если где то в коде есть ошибка компиляции - выбрасывает исключение, работа программы завершается и в консоль пишутся красные непонятные с первого раза слова. Которые объясняют что и где произошло. Если мы код где произошла ошибка обернем в try-catch. Программа поймет что мы знаем об этой ошибке и не будет останавливать работу программы, просто выполнит блок catch и дальше будет работать как не в чем небывало. throw-ить ошибку же надо для того, что бы программа после выполнения блока catch (в котором можно к примеру вывести в консоль "Тебе же написали вводи цифры, а не буквы") снова выбрасывало исключение, работа программы завершалась и в консоль летят красные непонятные слова. Которые объясняют что и где произошло.
Артём К Уровень 32
22 января 2025
спасибо добрый человек
Victor Уровень 38
29 января 2025
Что бы пользователь не пугался - выводим объявление - это обычной сбой, мол для бета версии обычное дело - всё под контролем. Ну дальше маска смерти............всё как обычно.
NightCrow Уровень 27
27 сентября 2024
Блин, а про Слона можно было дать хоть какие то пояснения? Я конечно догадываюсь, что при возникновении ошибки вываливается кэш, который копиться пока мы варимся внутри метода, вызывая его из себя же. Но это только мои догадки....
Ilya Klimchev Уровень 1
30 октября 2024
Не усложняйте) Рекурсивный вызов метода - это точно то же самое, что и вызов любого другого метода. Вас же не смущает, что в цепочке вызовов от main() до, например, System.out.println() могут быть сотни и тысячи методов? В памяти, при этом хранится контекст всех этих методов...и не только ;)
Sergo Уровень 22
2 сентября 2024
VAKHANDER Уровень 32
12 августа 2024
У меня появился странный вопрос, то есть придумали инструмент чтобы запускать код, который не должен работать? То есть например программист не хотел заморачиваться с написанием четкого алгоритма, сделал обработку исключения при неправильной операции и программа запускается работает а программист дальше получает деньги и блек джек и все такое?????
Wren Уровень 29
12 августа 2024
Ну почему же? try - catch помогает при ситуациях, которые ну никак не могут находиться под контролем программиста. Например, идет работа с файлами. Может ли программист гарантировать, что файл вообще существует? Может ли он гарантировать, что у программы точно будет доступ к файлу? А вдруг, если потребуется создать файл и туда что-то записать, на диске будет не хватать памяти и система банально откажет в записи?
CoreOne Уровень 23 Expert
19 июля 2024
Исключения интересны) а вот про Енам что то скучновато было)