Вы достигли нового уровня

Уровень 9

Знания vs. Навыки

Учеба в вузе приучила нас к мысли, что принципиальных отличий между теорией и практикой нет. Нет, вы конечно, понимаете, что это не одно и то же. Но принципиальной разницы не видите. А она есть.

Большинство людей ставит знак равенства между «я знаю» и «я умею». А вы – нет?

А как насчет таких примеров?

1) Я знаю, что курить вредно, но я – курю.

2) Я знаю, что МакДональдс вреден, но ем фастфуд.

3) Я знаю правила дорожного движения, но ездить не умею.

4) Я знаю, что бег полезен, но не бегаю по утрам.

Очень часто люди принимают «я знаю» за «я умею». Хороший пример с правилами дорожного движения. Если человек знает правила и знает, как ездить, значит ли это, что он умеет? Нет. А если он думает, что - значит? Ну и зачем ему инструктор, когда он уже и так все знает и умет?

Если вы уверены, что уже все знаете, то, скорее всего, ничего больше учить не будете. А если уверены, что все умеете, то ничему больше не научитесь. У вас и мысли такой не возникнет. А значит, вы упустите все замечательные возможности чему-нибудь научиться.

В обычном вузе вас кормят только знаниями, а умения/навыки вам придётся приобрести самим. Что я слышу? у вас в вузе была не только теория, но и практика?

Ок, если вы - студент физического факультета, сделайте мне рабочую модель парового двигателя с КПД хотя бы 20%. Спорю, что вы знаете как, но не умете, да?

Вы – химик? Сделайте черный бездымный порох. Тоже вроде бы знаете как, но не умеете?

Математик? Составьте уравнение полета артиллерийского снаряда. Не забудьте учесть форму снаряда. Материальные точки не летают в реальной жизни. Как не бывает и шарообразных коней.

Биолог? Выделите пенициллин. Это плесень, встречается на дынях, чтоб вы знали. Знаете как – отлично! Сможете?

Экономист? Постройте прогноз роста цен на нефть. Построили? А теперь превратите $2,000 в $200,000 за год на основании вашего прогноза. Вы хоть раз на FOREX играли? За реальные деньги? Или тоже только знаете, что это такое?

Международная экономика? Отлично! Где мне открыть офшор? В Гонконге, Ирландии или США. Почему? Даже если вы знаете, что вряд ли, вы не сможете этого сделать, т.к. никогда раньше не делали. И даже понятия не имеете, как это делается.

Вас этому в вузе не учили? Чего это я задаю задания, которые вы не проходили? А потому что это задания из реальной жизни. Это и есть практика, а все что вы учили в вузе: шарообразные кони, совершенная конкуренция – этого ничего в реальной жизни не существует.

Что же это я маркетологов забыл? Куда мне лучше потратить $500, чтобы о моем курсе узнало как можно больше людей? На рекламу? Вы вообще в курсе, что уже устарела не только классическая реклама, но и концепция Уникального Торгового Предложения, которая, как я уверен, преподносилась вам в вузе чуть ли не как панацея от всех бед?

Забудьте о том, что вы что-то знаете. Спросите себя – что вы умеете? Полезного? За что готовы платить деньги? Которых вам будет хватать?

Так что, друзья, давайте скажем спасибо такому замечательному курсу, как JavaRush. Благодаря которому, вы будете не только знать, как программировать, но и уметь программировать. А также сможете устроиться на работу, и, через пару лет, получать достойную зарплату. Которой, надеюсь, вам будет хватать для безбедной жизни.

Еще раз повторяю, чтобы запомнили: неважно, что вы знаете. Важно только то, что вы умеете делать полезного другим людям, за что они готовы платить вам деньги.

Чем раньше вы это поймете, тем лучше.



Хочешь стать программистом - купи подписку на полный курс. Более тысячи задач, 600+ минилекций, сайт, форум, плагин к IDEA, подсказки, видеоуроки, мотивирующие видео,... Это все будет твоим. JavaRush - реально крутой способ стать Java-программистом.

1. Стек трейс

- Привет! Сегодня я расскажу тебе, что такое стек-трейс. Но сначала расскажу, что такое стек.

- Представь себе стопку бумаг - деловых поручений для некоторого исполнителя. Сверху на стопку можно класть новое задание, и с верха стопки задание можно брать. При таком подходе задания будут исполняться не по порядку поступления. Задание, положенное самым последним, будет взято исполнителем самым первым. Такая структура элементов коллекции называется стеком – стопкой.

- В Java для этого есть специальная коллекция – Stack. Это коллекция, у которой есть методы «добавить элемент» и «взять(достать/забрать) элемент». Как ты уже догадался, первым будет взят элемент, добавленный самым последним.

- Хм. Вроде не сложно и понятно.

- Отлично. Тогда сейчас объясню, что такое стек-трейс.

- Представь себе, что в Java функция А вызвала функцию Б, а та вызвала функцию В, а та, в свою очередь, функцию Г. Так вот, чтобы выйти из функции Б, нужно сначала выйти из функции В, а для этого выйти из функции Г. Это очень похоже на стек.

- А чем похоже?

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

- Ну, некоторая аналогия есть, но не уверен, что я все понял правильно.

- Смотри. Стек – это набор элементов. Как листы в стопке. Чтобы взять третий сверху лист, надо сначала взять второй, а для этого взять первый. Класть и брать листы можно всегда, но всегда взять можно только самый верхний.

- С вызовом функций то же самое. Функция А вызывает функцию Б, а та вызывает функцию В. И чтобы выйти из А, надо сначала выйди из Б, а для этого надо выйти из В.

- Подожди. Если я все правильно понял, то весь этот стек сведется к «взять можно только самый последний положенный лист», «выйти можно только из последней функции, в которую зашли». Так?

- Да. Так вот – последовательность вызовов функций - это и есть «стек вызовов функций», он же просто «стек вызовов». Функция, вызванная последней, должна завершиться самой первой. Давай посмотрим это на примере:

Получение и вывод текущего стека вызовов:
public class ExceptionExample
{
  public static void main(String[] args)
  {
    method1();
  }

  public static void method1()
  {
    method2();
  }

  public static void method2()
  {
    method3();
  }

  public static void method3()
  {
    StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
    for (StackTraceElement element : stackTraceElements)
    {
       System.out.println(element.getMethodName());
    }
  }
}
Вот какой результат мы получим:
getStackTrace
method3
method2
method1
main

- Ок. С вызовом функций похоже все понятно. А что это еще за StackTraceElement?

- Java-машина ведет запись всех вызовов функций. У нее есть для этого специальная коллекция – стек. Когда одна функция вызывает другую, Java-машина помещает в этот стек новый элемент StackTraceElement. Когда функция завершается этот элемент удаляется из стека. Таким образом, в этом стеке всегда хранится актуальная информация о текущем состоянии «стека вызовов функций».

- Каждый StackTraceElement содержит информацию о методе, который был вызван. В частности можно получить имя этого метода с помощью функции getMethodName.

- В примере выше ты можешь видеть демонстрацию этого дела:

1) Получаем «стек вызовов»:

2) Проходимся по нему с помощью цикла for-each. Надеюсь, ты его еще не забыл.

3) Печатаем в System.out имена методов.

- Интересная штука и, похоже, совсем не сложная. Спасибо, Риша!

2. Задачи на вывод стек-трейса

- Привет, Амиго!

- Привет, Диего!

- Вот тебе одна маленькая задачка на вывод стек-трейса.

Задачи
1. Каждый метод должен возвращать свой StackTrace

Написать пять методов, которые вызывают друг друга. Каждый метод должен возвращать свой StackTrace.
2. И снова StackTrace

Написать пять методов, которые вызывают друг друга. Каждый метод должен возвращать имя метода, вызвавшего его, полученное с помощью StackTrace.
3. Метод должен вернуть номер строки кода, из которого вызвали этот метод

Написать пять методов, которые вызывают друг друга. Метод должен вернуть номер строки кода, из которого вызвали этот метод. Воспользуйся функцией: element.getLineNumber().
4. Стек-трейс длиной 10 вызовов

Напиши код, чтобы получить стек-трейс длиной 10 вызовов.
5. Метод должен возвращать результат – глубину её стек-трейса

Написать метод, который возвращает результат – глубину его стек трейса – количество методов в нем (количество элементов в списке). Это же число метод должен выводить на экран.

3. Знакомство с исключениями

- Привет, Амиго! Сегодня будет очень интересный урок. Сегодня я расскажу тебе об исключениях. Исключения – это специальный механизм для контроля над ошибками в программе. Вот примеры ошибок, которые могут возникнуть в программе:

1 Программа пытается записать файл на заполненный диск.

2 Программа пытается вызвать метод у переменной, которая хранит ссылку – null.

3 Программа пытается разделить число на 0.

Все эти действия приводят к возникновению ошибки. Обычно это приводит к закрытию программы - продолжать выполнять дальше код не имеет смысла.

- Почему?

- А есть ли смысл крутить руль, если машина слетела с трассы и падает с обрыва?

- Программа что, должна завершиться?

- Да. Раньше так и было. Любая ошибка приводила к завершению программы.

- Это очень разумный подход.

- А разве не лучше было бы попробовать работать дальше?

- Ага. Ты набрал большущий текст в Word’е, сохранил его, он не сохранился, но программа говорит тебе, что все в порядке. И ты продолжаешь набирать его дальше. Глупо, да?

- Ага.

- Потом разработчики придумали интересный ход: каждая функция возвращала статус своей работы. 0 означал, что она отработала как надо, любое другое значение – что произошла ошибка: это самое значение и было кодом ошибки.

- Но был у такого подхода и минус. После каждого(!) вызова функции нужно было проверять код (число), который она вернула. Во-первых, это было неудобно: код по обработке ошибок исполнялся редко, но писать его нужно было всегда. Во-вторых, функции часто сами возвращают различные значения – что делать с ними?

- Ага. Я тоже об этом подумал.

- Но потом наступило светлое будущее - появились исключения и механизм обработки ошибок. Вот как это работает:

1 Когда возникает ошибка, Java-машина создаёт специальный объект – exception – исключение, в который записывается вся информация об ошибке. Для разных ошибок есть разные исключения.

2 Затем это «исключение» приводит к тому, что программа тут же выходит из текущей функции, затем выходит из следующей функции, и так пока не выйдет из метода main. Затем программа завершается. Еще говорят, что Java-машина «раскручивает назад стек вызовов».

- Но ты же сказал, что теперь программа не обязательно завершается.

- Верно, потому что есть способ перехватить исключение. В нужном месте, для нужных нам исключений мы можем написать специальный код, который будет перехватывать эти исключения и что-то делать. Важное.

- Для этого есть специальная конструкция try-catch. Вот как это работает:

Вот пример программы, которая перехватывает исключение – деление на 0. И продолжает работать.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class ExceptionExample2
{
    public static void main(String[] args)
    {
        System.out.println("Program starts");

        try
        {
            System.out.println("Before method1 calling");
            method1();
            System.out.println("After method1 calling. Never will be shown");
        }
        catch (Exception e)
        {
           System.out.println("Exception has been caught");
        }

        System.out.println("Program is still running");
    }

    public static void method1()
    {
        int a = 100;
        int b = 0;
        System.out.println(a / b);
    }
}
Вот что будет выведено на экран:
5
9
15
18
"Program starts"
"Before method1 calling"
"Exception has been caught"
"Program is still running"

- А почему не будет выведено «After method1 calling. Never will be shown»?

- Рада, что ты спросил. В строчке 25 у нас было деление на ноль. Это привело к возникновению ошибки – исключения. Java-машина создала объект ArithmeticException с информацией об ошибке. Этот объект является исключением.

- Внутри метода method1 возникло исключение. И это привело к немедленному завершению этого метода. Оно привело бы и к завершению метода main, если бы не было блока try-catch.

- Если внутри блока try возникает исключение то, оно захватывается в блоке catch. Остаток кода в блоке try, не будет исполнен, а сразу начнётся исполнение блока catch.

- Как-то не очень понятно.

- Другими словами этот код работает так:

1 Если внутри блока try возникло исключение, то код перестаёт исполняться, и начинает исполняться блок catch.

2 Если исключение не возникло, то блок try исполняется до конца, а catch никогда так и не начнёт исполняться.

- Гм?

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

- Теперь вроде понятно.

- Вот и отлично.

- А что значит Exception внутри catch?

- Все исключения – это классы, унаследованные от класса Exception. Мы можем перехватить любое из них, указав в блоке catch его класс, или все сразу, указав общий родительский класс - Exception. Затем из переменной e (эта переменная хранит ссылку на объект исключения), можно получить всю необходимую информацию о возникшей ошибке.

- Круто! А если в моем методе могут возникнуть разные исключения, можно обрабатывать их по-разному?

- Не можно, а нужно. Сделать это можно вот так:

Пример:
public class ExceptionExample2
{
    public static void main(String[] args)
    {
        System.out.println("Program starts");

        try
        {
            System.out.println("Before method1 calling");
            method1();
            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");
        }

        System.out.println("Program is still running");
    }

    public static void method1()
    {
        int a = 100;
        int b = 0;
        System.out.println(a / b);
    }
}

- Блок try может содержать несколько блоков catch, каждый из которых будет захватывать исключения своего типа.

- Гм. Ну, вроде понятно. Сам такого не напишу, конечно, но если в коде встречу – пугаться не буду.

4. RuntimeException, throw

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

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

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

- Ок.

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

Примеры проверяемых (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.");
    }
}

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

5. Раскрутка стека вызовов, как это идёт при исключениях

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

Код с использованием исключений Примерная расшифровка
class ExceptionExampleOriginal
{


    public static void main(String[] args)
    {
        System.out.println("main begin");
        try
        {
            System.out.println("main before call");

            method1();



            System.out.println("main after call");
        }
        catch (RuntimeException e)
        {


            String s = e.getMessage();
            System.out.println(s);
        }
        System.out.println("main end");
    }

    public static void method1()
    {
        System.out.println("method1 begin");
        method2();

        System.out.println("method1 end");
    }

    public static void method2()
    {
      System.out.println("method2");
      String s = "Message: Unknown Exception";
      throw new RuntimeException(s);

    }
}
public class ExceptionExample
{
    private static Exception exception = null;

    public static void main(String[] args)
    {
        System.out.println("main begin");

       
        System.out.println("main before call");

        method1();

        if (exception == null)
        {
            System.out.println("main after call");
        }
        else if (exception instanceof RuntimeException)
        {
            RuntimeException e = (RuntimeException) exception;
            exception = null;
            String s = e.getMessage();
            System.out.println(s);
        }
        System.out.println("main end");
    }

    public static void method1()
    {
        System.out.println("method1 begin");
        method2();
        if (exception != null) return;
        System.out.println("method1 end");
    }

    public static void method2()
    {
        System.out.println("method2");
        String s = "Message: Unknown Exception";
        exception = new RuntimeException(s);
        return;
    }
}

- Ничего не понятно.

- Ок. Давай я тебе объясню, что происходит.

- В примере слева мы по цепочке вызываем несколько методов. В method2 мы специально создаем и выкидываем исключение (инициируем ошибку).

- В примере справа показано, что примерно при этом происходит.

- Посмотри на method2. Создание исключение превратилось вот во что: создали объект типа RuntimeException, сохранили его в специальную переменную exception и тут же вышли из метода – return.

- В методе method1, после вызова method2 стоит проверка – есть исключение или нет, если исключение есть, тогда метод method1 тут же завершается. Такая проверка неявно производится после вызова каждого(!) метода в Java.

- Ого!

- Вот тебе и ого.

- В колонке справа в методе main я написал, что примерно происходит при перехвате исключения с помощью конструкции try-catch. Если исключения не было, то все продолжает работать, как и запланировано. Если исключение было, и оно было такого типа, как указано в catch, тогда мы его обрабатываем.

- А что значит throw и instanceof?

– Посмотри на последнюю строку throw new RuntimeException(s). Таким способом мы создаем и кидаем исключение. Пока мы так делать не будем. Это только для примера.

- А с помощью команды «а instanceof B» мы проверяем, имеет ли объект a тип B. Т.е. имеет ли объект, который хранится в переменной exception, тип RuntimeException. Это логическое условие.

- Ну, вроде понятно. Немного.

6. Задача на захват исключений

- Привет, Амиго! Вот тебе интересные задачи на захват исключений.

Задачи
1. Исключение при работе с числами

Перехватить исключение (и вывести его на экран), указав его тип, возникающее при выполнении кода:
int a = 42 / 0;
2. Исключение при работе со строками

Перехватить исключение (и вывести его на экран), указав его тип, возникающее при выполнении кода:
String s = null;
String m = s.toLowerCase();
3. Исключение при работе с массивами

Перехватить исключение (и вывести его на экран), указав его тип, возникающее при выполнении кода:
int[] m = new int[2];
m[8] = 5;
4. Исключение при работе с коллекциями List

Перехватить исключение (и вывести его на экран), указав его тип, возникающее при выполнении кода:
ArrayList<String> list = new ArrayList<String>();
String s = list.get(18);
5. Исключение при работе с коллекциями Map

Перехватить исключение (и вывести его на экран), указав его тип, возникающее при выполнении кода:
HashMap<String, String> map = new HashMap<String, String>(null);
map.put(null, null);
map.remove(null);

- Подсказка: напиши программу, посмотри, какое исключение возникает, а потом поменяй код и перехвати его.

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

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

- Хочу рассказать тебе, как работает множественный 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.

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

8. Задачи на захват множественных исключений

- Привет, Амиго! Я вчера напился и намудрил с твоими задачами, но ты же на меня не в обиде и все решишь? Это для твоего же блага. Держи:

Задачи
1. Исключения

Есть метод, который выбрасывает два исключения, унаследованные от Exception, и два унаследованных от RuntimeException: NullPointerException, ArithmeticException, FileNotFoundException, URISyntaxException.

Нужно перехватить NullPointerException и FileNotFoundException, но не перехватывать ArithmeticException и URISyntaxException. Как это сделать?
2. Перехватывание исключений

Есть три исключения последовательно унаследованные от Exception:
class Exception1 extends Exception
class Exception2 extends Exception1
class Exception3 extends Exception2
Есть метод, который описан так:
public static void method1() throws Exception1, Exception2, Exception3

Напиши catch, который перехватит все три Exception1, Exception2 и Exception3
3. Перехват выборочных исключений

1. Разберись, какие исключения бросает метод BEAN.methodThrowExceptions.
2. Метод processExceptions должен вызывать метод BEAN.methodThrowExceptions и обрабатывать исключения:
2.1. если возникло исключение FileSystemException, то логировать его (вызвать метод BEAN.log) и пробросить дальше
2.2. если возникло исключение CharConversionException или любое другое IOException, то только логировать его - вызвать метод BEAN.log
3. Добавь в сигнатуру метода processExceptions класс исключения, которое ты пробрасываешь в п.2.1.
4. В методе main обработай оставшееся исключение - логируй его. Используй try..catch

Подсказка:
Если ты захватил исключение MyException, которое не хотел захватывать, его можно пробросить дальше кодом вида:
catch (MyException e) {
   throw e;
}
4. Перехват checked исключений

В методе processExceptions обработайте все checked исключения.
Нужно вывести на экран каждое возникшее checked исключение.
Можно использовать только один блок try.
5. Перехват unchecked исключений

В методе processExceptions обработайте все unchecked исключения.
Нужно вывести стек-трейс каждого возникшего исключения используя метод printStack.
Можно использовать только один блок try.

9. Лекция по исключениям

- Сегодня я расскажу супер интересную тему – исключения. В своё время эта тема будоражила умы молодых учёных и программистов…

- Прости, мне нужно в лабораторию. Вот тебе конспект лекций. Думаю, ты сам разберёшься. Держи вот: Лекция по исключениям

10. Хулио

- Амиго, как тебе сегодняшнее занятие? Твои позитронные мозги ещё не плавятся? Диего кого угодно доконает своими задачами. Предлагаю взять по пиву и расслабиться. Ты ещё стоишь?

Оригинал видео на YouTube

11. Капитан

- Здорово, боец!

- Здравия желаю, капитан Бобров!

- У меня для тебя шикарная новость. Вот тебе задания для закрепления полученных навыков. Выполняй их каждый день, и твои навыки будут расти с неимоверной скоростью. Они специально разработаны для выполнения их в Intellij IDEA.

Дополнительные задания для выполнения в Intellij Idea
1. Деление на ноль

Создай метод public static void divisionByZero, в котором подели любое число на ноль и выведи на экран результат деления.
Оберни вызов метода divisionByZero в try..catch. Выведи стек-трейс исключения используя метод exception.printStackTrace()
2. Обратный отсчёт от 10 до 0

Написать в цикле обратный отсчёт от 10 до 0. Для задержки иcпользовать Thread.sleep(100);
Обернуть вызов sleep в try..catch.
3. Метод в try..catch

Вводить с клавиатуры числа. Код по чтению чисел с клавиатуры вынести в отдельный метод readData.
Обернуть все тело (весь код внутри readData, кроме объявления списка, где будут храниться числа и BufferedReader - а) этого метода в try..catch.
Если пользователь ввёл какой-то текст, вместо ввода числа, то метод должен перехватить исключение и вывести на экран все введенные числа в качестве результата.
Числа выводить с новой строки сохраняя порядок ввода.
4. Конвертер дат

Ввести с клавиатуры дату в формате «08/18/2013»
Вывести на экран эту дату в виде «AUG 18, 2013».
Воспользоваться объектом Date и SimpleDateFormat.
5. Гласные и согласные буквы

Написать программу, которая вводит с клавиатуры строку текста.
Программа должна вывести на экран две строки:
1) первая строка содержит только гласные буквы
2) вторая - только согласные буквы и знаки препинания из введённой строки.
Символы соединять пробелом, каждая строка должна заканчиваться пробелом.

Пример ввода:
Мама мыла раму.
Пример вывода:
а а ы а а у
М м м л р м .
6. Сказка «Красная Шапочка»

1. Есть пять классов: красная шапочка, бабушка, пирожок, дровосек, волк.
2. У каждого класса есть 2 поля: убил (killed ArrayList) и съел (ate ArrayList).
3. Необходимые объекты созданы (hood, grandmother, ...).
4. Расставь правильно связи, кто кого съел и убил, чтобы получилась логика сказки «Красная Шапочка».
7. Расставь модификаторы static

Расставь модификаторы static так, чтобы пример скомпилировался
8. Список из массивов чисел

Создать список, элементами которого будут массивы чисел. Добавить в список пять объектов–массивов длиной 5, 2, 4, 7, 0 соответственно. Заполнить массивы любыми данными и вывести их на экран.
9. Десять котов

Создать класс кот – Cat, с полем «имя» (String).
Создать словарь Map(<String, Cat>) и добавить туда 10 котов в виде «Имя»-«Кот».
Получить из Map множество(Set) всех имен и вывести его на экран.

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

1. Нужно исправить программу, чтобы компилировалась и работала.

Задача: Программа вводит два имени файла. И копирует первый файл на место, заданное вторым именем.
2. Нужно добавить в программу новую функциональность.

Задача: Программа вводит два имени файла. И копирует первый файл на место заданное вторым именем.
Новая задача: Программа вводит два имени файла. И копирует первый файл на место, заданное вторым именем.
Если файла (который нужно копировать) с указанным именем не существует, то программа должна вывести надпись «Файл не существует.» и еще раз прочитать имя файла с консоли, а уже потом считывать файл для записи.
3. Задача по алгоритмам.

Задача: Пользователь вводит с клавиатуры список слов (и чисел). Слова вывести в возрастающем порядке, числа - в убывающем.

Пример ввода:
Вишня
1
Боб
3
Яблоко
2
0
Арбуз

Пример вывода:
Арбуз
3
Боб
2
Вишня
1
0
Яблоко