JavaRush/Курсы/Java Collections/throwable, multiple exceptions, эксепшн внутри метода fin...

throwable, multiple exceptions, эксепшн внутри метода finalize

Открыта

— Ага. Вот ты где. Я уже тебя обыскалась.

— Что-то случилось?

— Нет, но мы же занимаемся.

— Ок. Я тебя слушаю.

— Я хочу тебе рассказать об исключениях еще пару фактов:

В Java 7 конструкция try-catch была немного расширена за счет добавления «множественных catch». Смотри пример:

Java 5
try
{
  …
}
 catch (IOException ex)
{
 logger.log(ex);
 throw ex;
}
 catch (SQLException ex)
{
 logger.log(ex);
 throw ex;
}
Java 7
try
{
  …
}
 catch (IOException | SQLException ex)
{
 logger.log(ex);
 throw ex;
}

— Т.е. теперь можно писать несколько исключений через ИЛИ ( «|» — это бинарный ИЛИ)?

— Да, правда, удобно?

— Гм. А какой тип будет у этого объекта-исключения внутри блока catch?

Ведь у IOException могут быть свои методы, а у SQLException – свои.

— Тип исключения будет такой же, как и у их общего класса-предка.

— Ага. Т.е. скорее всего Exeption или RuntimeException. Почему тогда просто не написать catch(Exception e)?

— Иногда, когда программисты обрабатывают все ошибки отдельно, бывает удобно разбить их на группы и одни ошибки записать в лог, другие пробросить выше, третьи обработать иным способом.

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

— Ага. Понято. Спасибо, Элли.

— Это еще не все, я хочу еще рассказать немного про блок finally.

Как ты уже, наверное, знаешь, этот блок выполняется всегда.

Когда я говорю всегда, я имеют ввиду абсолютно всегда.

Пример:

Пример с finally
try
{
 return 1;
}
 finally
{
 return 0;
}

Тут есть return в блоке try и return в блоке finally. Так вот, результатом вызова метода будет число 0.

Блок finally выполнится, что бы ни произошло. А его метод return перезатер старое возвращаемое значение своим значением.

— Ясно.

Более того, метод может либо вернуть значение, либо выбросить исключение.

Поэтому, если в блоке try возвращается значение, а в finally выбрасывается исключение, то в результате будет исключение.

— А если в блоке try выбрасывается исключение, а в блоке finally выполняется return?

Тогда считается, что метод корректно отработал и возвращается значение, которое было передано в return.

Пример Результа
try
{
 return 1;
}
 finally
{
 return 0;
}
0
try
{
 return 1;
}
 finally
{
 throw new RuntimeException();
}
RuntimeException
try
{
 throw new RuntimeException();
}
 finally
{
 return 0;
}
0
try
{
 throw new RuntimeException();
}
 finally
{
 throw new IOException();
}
IOException

Единственной причиной, по которой может не выполниться метод finally, может быть немедленное завершение программы посредством вызова метода System.exit();

Пример
try
{
 System.exit(0);
 return 1;
}
 finally
{
 return 0;
}

— Ясно.

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

Комментарии (20)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Long_byte
Уровень 60
16 октября 2024, 19:50
как работает вообще механизм блока finally?
Андрей
Уровень 51
21 мая 2024, 06:44
еще finally может не выполниться в потоках-демонах, если они завершат работу вместе с главным потоком
Fl1s Backend Developer
26 марта 2024, 13:51
Ужс
Kurama
Уровень 50
7 апреля 2023, 17:27
Ладно, этого я не знал
lightning
Уровень 41
26 августа 2021, 11:19
— Гм. А какой тип будет у этого объекта-исключения внутри блока catch? Ведь у IOException могут быть свои методы, а у SQLException – свои. — Тип исключения будет такой же, как и у их общего класса-предка. Стоит добавить, что класс предка будет использоваться только в пределах блока catch в котором перехвачено исключение. Если пробросить его дальше, то оно будет иметь исходный тип. Даже если перехватывать Exception и пробрасывать его далее, то в вышестоящем методе исключение будет иметь исходный тип. Т.е. нижеприведенный код будет выводить :
void f() {
      if (((int) (Math.random() * 2)) ==1 ) throw new NullPointerException();
      else throw new ArrayIndexOutOfBoundsException();
}

void g() {
      try {
          f();
      }
      catch (NullPointerException | ArrayIndexOutOfBoundsException e) {
          throw e;
      }
 }

void j() {
      try {
          g();
      }
      catch (NullPointerException e) {
          System.out.println("NullPointerException");
      }
      catch (ArrayIndexOutOfBoundsException e) {
          System.out.println("ArrayIndexOutOfBoundsException");
      }
}
Pig ManГлавная свинья в Свинарнике
23 февраля 2021, 10:04
Предыдущая лекция: "Считать исключение ошибками – это неверный подход" Эта лекция: "Когда программисты обрабатывают все ошибки отдельно" Как людям правильно соблюдать терминологию, если даже учителя ее не соблюдают?
Андрей
Уровень 41
5 февраля 2021, 21:08
Javarush, посмотрите эту страницу. На ней куча опечаток. Пожалуйста исправьте.
Ars
Уровень 41
29 ноября 2021, 12:30
Всё ещё не везде исправили. Например в предпоследнем блоке кода столбец называется "Результа"
skrskr
Уровень 39
5 февраля 2020, 19:50
Есть объяснение почему нельзя использовать сокращённые операторы, а не только побитовые?
ИльяBackend Developer в СберТех
18 февраля 2021, 12:50
ты написал одно и тоже))))
LuneFoxJava Developer в BIFITExpert
8 марта 2022, 06:10
Он разное написал. Сокращённый это ||, а под побитовым имеется в виду |.
Игорь
Уровень 41
14 июня 2019, 08:02
А где про эксепшн внутри метода finalize?
7 апреля 2020, 04:34
Видимо опечатались в названии лекции. Вот может кому понадобиться. Вопрос Что произойдет со сборщиком мусора (GC), если во время выполнения метода finalize() некоторого объекта произойдет исключение? Ответ Во время старта JVM запускается поток finalizer, который работает в фоне. Этот поток имеет метод runFinalizer, который игнорирует все исключения методов finalize объектов перед сборкой мусора. То есть если во время выполнения метода finalize возникнет исключительная ситуация, его выполнение будет остановлено и это никак не скажется на работоспособности самого сборщика мусора (garbage collector). http://www.quizful.net/interview/java/exception-while-finalize
Пётр
Уровень 41
Expert
26 апреля 2019, 18:35
finally, насколько помню, не выполняется при System.exit(0) или (-1) в catche или основном коде