Типы исключений

Открыта

— Решила поднять сегодня ещё одну тему. В Java все исключения делятся на два типа – контролируемые/проверяемые (checked) и неконтролируемые/непроверяемые (unchecked): те, которые перехватывать обязательно, и те, которые перехватывать не обязательно. По умолчанию – все исключения обязательно нужно перехватывать.

— А можно в коде специально выбрасывать исключения?

— В своем коде ты сам можешь выкидывать исключения. Ты даже можешь написать свои собственные исключения. Но это мы разберем позже. Сейчас же давай научимся работать с исключениями, которые выбрасывает Java-машина.

— Ок.

— Если в методе выбрасываются (возникают) исключения ClassNotFoundException и FileNotFoundException, программист обязан указать их в сигнатуре метода (в заголовке метода). Это checked исключения. Вот как это обычно выглядит:

Примеры
public static void method1() throws ClassNotFoundException, FileNotFoundException
public static void main() throws IOException
public static void main() //не выбрасывает никаких исключений

— Т.е. мы просто пишем throws и перечисляем исключения через запятую. Так?

— Да. Но тут интересно другое. Чтобы программа скомпилировалась, метод, который вызывает method1 в примере ниже, должен сделать две вещи: или перехватить эти исключения или пробросить их дальше (тому, кто его вызвал), указав их в своём заголовке.

— Еще раз. Если ты в методе main хочешь вызвать метод какого-то объекта, в заголовке которого прописано throws FileNotFoundException, … то тебе надо сделать одно из двух:

1) Перехватывать исключения FileNotFoundException, …

Тебе придется обернуть код вызова опасного метода в блок try-catch

2) Не перехватывать исключения FileNotFoundException, …

Тебе придется добавить эти исключения в список throws своего метода main.

— А можно пример?

— Вот, смотри:

Примеры проверяемых (checked) исключений
public static void main(String[] args)
{
    method1();
}

public static void method1() throws FileNotFoundException, ClassNotFoundException
{
    //тут кинется исключение  FileNotFoundException, такого файла нет
    FileInputStream fis = new FileInputStream("C2:\badFileName.txt");
}

— Этот пример не скомпилируется, т.к. метод main вызывает метод method1(), который выкидывает исключения, обязательные к перехвату.

— Чтобы пример скомпилировался, надо добавить обработку исключений в метод main. Сделать это можно двумя способами:

Способ 1: просто пробрасываем исключение выше (вызывающему):
public static void main(String[] args)  throws FileNotFoundException, ClassNotFoundException
{
    method1();
}

public static void method1() throws FileNotFoundException, ClassNotFoundException
{
    //тут кинется исключение  FileNotFoundException, такого файла нет
    FileInputStream fis = new FileInputStream("C2:\badFileName.txt");
}

— А тут перехватываем его с помощью try-catch:

Способ 2: перехватываем исключение:
public static void main(String[] args)
{
    try
    {
        method1();
    }
    catch(Exception e)
    {
    }
}

public static void method1() throws FileNotFoundException, ClassNotFoundException
{
    //тут кинется исключение  FileNotFoundException, такого файла нет
    FileInputStream fis = new FileInputStream("C2:\badFileName.txt");
}

— Что-то понемногу проясняется.

— Посмотри на пример ниже, чтобы разобраться:

Не обрабатываем исключения – нужно пробросить их дальше, тому, кто знает как
public static void method2() throws FileNotFoundException, ClassNotFoundException
{
    method1();
}
Обрабатываем одно исключение, второе – пробрасываем:
public static void method3() throws ClassNotFoundException
{
   try
    {
        method1();
    }
    catch (FileNotFoundException e)
    {
        System.out.println("FileNotFoundException has been caught.");
    }
}
Перехватываем оба – ничего не пробрасываем:
public static void method4()
{
    try
    {
        method1();
    }
    catch (FileNotFoundException e)
    {
        System.out.println("FileNotFoundException has been caught.");
    }
    catch (ClassNotFoundException e)
    {
        System.out.println("ClassNotFoundException has been caught.");
    }
}
2
Задача
Java Syntax,  9 уровень,  4 лекция
Недоступна
Набираем код
Внимание! Объявляется набор кода на JavaRush. Для этого включите режим повышенной внимательности, расслабьте пальцы, читайте код и… набирайте его в соответствующем окошке. Набор кода — вовсе не бесполезное занятие, как может показаться на первый взгляд: благодаря ему новичок привыкает к синтаксису и запоминает его (современные IDE редко дают ему это сделать).

— Но есть вид исключений – это RuntimeException и классы, унаследованные от него. Их перехватывать не обязательно. Это unchecked исключения. Считается, что это трудно прогнозируемые исключения и предсказать их появление практически невозможно. С ними можно делать все то же самое, но указывать в throws их не нужно.

Комментарии (102)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий вы должны авторизоваться
Edward17 уровень
3 октября, 07:07
Throws - это предупреждение для программиста, который будет использовать помеченный так метод. Это своеобразное извещение о возможности появления исключительных ситуаций в процессе использования помеченного метода. Или, выражаясь по-другому, уведомление о наличии в коде класса операций, конструкции и действия которых невозможно запрограммировать так, чтобы исключить появление ошибки. Это сигнал, что есть риск возникновения необработанной ошибки. Сигнал как для программиста, так и для среды разработки, которая запрещает использование метода помеченного "throws" без обработки исключительной ситуации! ИМХО Но называть такую пометку (уведомление\ извещение\ предупреждение\ запрет на использование без обработки исключения\ сигнал о наличии риска возникновения исключительной ситуации - я могу ещё много НАМНОГО БОЛЕЕ ПОДХОДЯЩИХ СИНОНИМОВ придумать) "пробрасыванием" "пробросом" "выбрасыванием" - это абсолютно бессмысленно для русскоговорящего человека. Для общения с иностранцами на русском языке - ок, чтобы был прямой перевод "throws - бросать", но для обучения этот термин просто ужасен, крайне непонятен и дико сводит с толку программистов даже владеющих английским языком на уровне выше elementary, не говоря уже про людей вообще не владеющих разговорным английским. Опять же ИМХО, не позиционирую своё мнение как эталон или претендующее на авторитетность, просто бомбит с этого термина и хочется пообщаться) А что вы думаете по этому поводу? Что ещё хотелось бы дополнить. Возможно для кого-то это не очевидно. Однако у некоторых может возникнуть вопрос, а почему нельзя писать такой код, чтобы вообще не возникало ошибок? Ведь если вы ставите пометку (ключевое слово, предупреждение) throws, то почему бы самому вместо этого не запихать всё тело вашего метода или возможное место появления исключения в блок try-catch? Ведь вы знаете что риск есть, не от балды же появляется throws в заголовке метода!
Justinian41 уровень, Киев
9 октября, 03:41
Сложно сказать. throws это ключевое слово которое обозначает, что метод может передать вверх по стеку исключение. Или пробрасывает исключение выше к caller method. throw new SomeException говорит о том, что будет выброшено какое-то исключение. Если оно в блоке try..catch можно говорить о том, что оно проброситься вверх. В английском употребляют глагол to propagate, чуть реже rethrow. Перевод как перевод. А как лучше? Если исключение бросается, это слово которое подчеркивает неожиданный и резкий характер действия, то когда бросается несколько раз (а эксепшен может "путешествовать" по стеку от метода к методу), почему бы не назвать проброской. уведомление\ извещение\ предупреждение\ запрет на использование без обработки исключения\ сигнал о наличии риска возникновения исключительной ситуации эти варианты которые освещают одну сторону, информационную, но с другой стороны, получается что назвать throws clause проброской можно расценить как неточностью, как например Human michael = new Student(); cказать что michael у нас это объект тип Студент. Или int[] numbers = {1, 2, 3, 4, 5}; назвать numbers массивом. Но это неверно. Поскольку michael это имя ссылочной переменной типа Human, которая указывает на объект типа Студент. А numbers это ссылочная переменная, которая указывает на массив интов. Но как по мне, такие допущения вполне уместны. Но это мои мысли, никогда об этом не задумывался. В подобных ситуациях, когда устоявшийся перевод терминов меня напрягает, я просто использую английский вариант и все. Это вполне допустимо, даже для глаголов, речь профессионального программиста все-равно часто похожа на суржик родного и английского языка, это норма для профессии, мы используем в нашей речи огромнейшее количество слов иностранного происхождения. Если мы используем в речи слова делегат, инструкция программа или метод, почему не можем идти дальше и добавить пару слов? Это допустимо правилами языка, ибо профессиональная лексика.
Ilya10 уровень, Москва
9 сентября, 14:53
Ребята, вы можете убрать авто добавление закрывающих скобок и кавычек? Реально бесит, что необходимо либо их затирать вручную, либо мириться с тем, что код будет "красным" до самого конца. И если будет ошибка, придется разбирать код. Вы реально думаете, что кому-то это нужно?
Олег20 уровень, Запорожье
9 сентября, 19:06
Тоже бесило это, пока не прочитал, что надо ставить пробел после открывающейся скобки и только после этого нажимать на Enter!
Ilya10 уровень, Москва
10 сентября, 08:50
Спасибо за подсказку ;-)
Константин Кухарь9 уровень, Харьков
3 октября, 12:44
Пробелы не учитываются при валидации?
Олег20 уровень, Запорожье
4 октября, 18:14
В данных задачах - нет. Это вы можете проверить по зеленому фону.
Дмитрий15 уровень, Волгоград
30 августа, 10:40
Не ленитесь набирать код, после таких, казалось бы унылых заданий, всё равно инфа откладывается в голове, уже много раз убеждался в этом.
Алексей14 уровень, Полысаево
8 октября, 07:44
А еще лучше ручкой на бумаге записать. Набор текста это одна нервная деятельность, а запись на бумаге уже другая - намного более ресурсозатратная для мозга(инфа откладывается лучше)
12311 уровень, город
29 июля, 15:55
Скорее всего позже я найду ответ на этот вопрос, но вдруг кто раньше подскажет - где и каким образом обрабатываются исключения, если их выбрасывает метод main() ?
valijon li26 уровень, Москва
29 июля, 19:52
Ты лучше над этих голову не ломай, как то что то понял, иди дальше! Со временем как решаеш задачки, ты сам по тихонечку освоиваеш. Если много застрянешь на одной тему, потеряешь мотивацию. Только вперёд!!!
Dan Banan13 уровень, Великий Новгород
20 августа, 12:16
Думаю их ловит стандартный обработчик исключений, который есть всегда. Но это не точно)
Eiffil19 уровень, Москва
4 сентября, 20:17
Если в методе main исключения не обработаны, а идут дальше, то программа завершится аварийно. Наверно, если разработка ведется в какой-то IDE, эти исключения перехватятся средой разработки, чтобы показать пользователю.
Олег20 уровень, Запорожье
9 сентября, 19:13
Тоже задался этим вопросом. Смысл было тянуть "выбрасывание исключения" аж до main, чтобы его потом НИГДЕ не обрабатывать! Не понятно......
Константин Кухарь9 уровень, Харьков
3 октября, 12:46
Мейн не может пробрасысать исключения, и сам метод должен обработать все исключения которые пробрасываются ему из вызываемых классов. Если в мейне появится исключение которое не было обработано - ваше приложение приляжет отдохнуть
Alexandr22 уровень
5 мая, 15:26
"В Java все исключения делятся на два типа – контролируемые/проверяемые (checked)" (ЗЕЛЕНЫЙ) "и неконтролируемые/непроверяемые (unchecked)" (КРАСНЫЙ). Действительно, поменяйте пожалуйста цвета шрифта (checked) на ЖЕЛТЫЙ и (unchecked) на ЗЕЛЕНЫЙ.
Vitaliy23 уровень, Санкт-Петербург
30 апреля, 12:46
Alex40 уровень
3 мая, 11:56
Спасибо, исправим.
Mikhail Kokorin18 уровень, Санкт-Петербург
26 апреля, 09:11
Такое чувство что создатели специально пишут так статьи,что бы они смотрелись так, как будь то их от куда то вырезали и вставили сюда...да еще эти манипуляции с покраской слов в другие цвета как будь то наоборот запутать хотят.
Aeon15 уровень, Санкт-Петербург
31 марта, 18:53
На первой схеме Runtime Exception и его потомки изображены зеленым цветом и в первом же абзаце зеленым написано про "контролируемые/проверяемые (checked)" исключения. А вот уже в конце иначе: "но есть вид исключений – это RuntimeException и классы, унаследованные от него. Их перехватывать не обязательно. Это unchecked исключения". Неужели нельзя по-человечески преподнести материал, чтобы я не тратил время, разбираясь, checked это или все-таки unchecked? Очередная статья, после которой сразу же нужно идти гуглить.
Шкипер16 уровень, Минск
27 марта, 08:41
как быстрее всего набирать код. 1. Открываем Chrome 2. Разворачиваем задание "Набираем код" 3. Фокусируем курсор в поле "Код, который надо повторить:" 4. Жмем CTRL+A (выделение кода не видно, но оно есть =), затем CTRL+C. 5. Фокусируем курсор в поле "Ваш код:" 6. Жмем CTRL+V Если помогло, то ставь лайк!
Семён22 уровень, Екатеринбург
27 марта, 23:38
это нужно для того, чтобы тренироваться набирать код ручками и для усвоения материала, а не для зарабатывания черной материи
Шкипер16 уровень, Минск
28 марта, 11:57
я никого не агитирую пользоваться моей инструкцией, но набрать код, достаточно было на 1-7 уровнях. Сейчас нужно понимание того, что ты делаешь, а IDEA поможет автоматизировать то что ты делаешь. Вы серьезно всё еще вручную описываете конструкцию try-catch? Достаточно выделить в IDE строку и нажать CTRL+ALT+T.
Семён22 уровень, Екатеринбург
28 марта, 12:02
может быть при чтении чужого кода может помочь
Шкипер16 уровень, Минск
28 марта, 12:13
Набирание кода , может помочь при чтении чужого кода? я правильно вас понял?
Семён22 уровень, Екатеринбург
28 марта, 13:29
набирание кода ведет к лучшей запоминаемости и понимания синтаксиса
Шкипер16 уровень, Минск
29 марта, 12:41
facepalm
Kirill Sadovnikov16 уровень, Санкт-Петербург
11 мая, 20:23
1. Открываешь консоль браузера 2. Нажимаешь на кнопку аля набор 3. В запросе после нажатия кнопки прилетит base64 строка с кодом 4. Декодируешь строку и пихаешь в textarea с набором кода 5. PROFIT
Mykola17 уровень, Helsinki
14 июня, 15:42
Слышал что в конце курса черную материю на баксы будут мннять🤣🤣🤣
Сергей Novichok15 уровень, Нижний Новгород
17 июля, 17:07
Да, IDEA расслабляет. А если когда-нибудь, на каком-нибудь старом-старом лэптопе не окажется ничего, кроме блокнота и командной строки ...
Шкипер16 уровень, Минск
13 августа, 13:34
значит, плохой программист, который будет что-то делать на старом-старом лэптопе.
Oleg Zaytsev24 уровень
2 марта, 22:39
https://javarush.ru/groups/posts/1401-iskljuchenija-i-ikh-obrabotka