„Здрасти, Амиго. Днес ще имаме много интересен урок. Ще ти разкажа за изключенията. Изключенията са специален механизъм, който ни позволява да обработваме грешки в програмата. Ето някои примери за грешки, които могат да възникнат в програма:

1. Програмата може да се опита да запише файл, когато твърдият диск е напълно пълен.

2. Програмата може да опита да извика метод на променлива, съхраняваща нулева препратка.

3. Програмата може да се опита да раздели число на 0."

Всички тези действия водят до грешки. Обикновено резултатът е, че програмата незабавно спира, тъй като в този случай няма смисъл да продължавате да изпълнявате code.

"Защо?"

„Има ли смисъл да продължаваме да въртим колело, ако колата е излязла от пътя и пада от скала?“

„Трябва ли програмата да спре да работи тогава?“

"Да. Поне така се случваше. Всяка грешка караше програмата да прекъсва."

"Това е много умен подход."

„Но не би ли било по-добре да опитате и да продължите да изпълнявате програмата?“

„Да. Да предположим, че сте въвели огромно количество текст в Word и сте го запазor. Ами ако операцията за запазване е неуспешна, но програмата ви кара да вярвате, че всичко е наред? И продължавате да пишете. Това би било глупаво, нали то?"

— Да.

„Тогава програмистите излязоха с интересно решение: всяка функция ще върне статуса на своята работа. 0 означава, че работи според очакванията. Всяка друга стойност ще означава, че е възникнала няHowва грешка, а върнатата стойност е code на грешка.“

„Този ​​подход обаче има и своите недостатъци. След всяко (!) извикване на функция трябва да проверите codeа за връщане (номер). Първо, това е неудобно: codeът за обработка на грешки рядко се изпълнява, но трябва да бъде включен навсякъде. Второ, функциите често връщат различни стойности - Howво трябва да правите с тях?"

— Добре. И аз си помислих за това.

„Тогава се появи светло бъдеще под формата на изключения и механизъм за обработка на грешки. Ето How работи:

1. Когато възникне грешка, Java машината създава специален обект – изключение – където записва цялата информация за грешката. Има различни изключения за различни грешки.

2. Изключение кара програмата незабавно да излезе от текущата функция, от следващата функция и така нататък – докато излезе от основния метод. След това програмата се прекратява. Програмистите могат също така да кажат, че Java машината „отвива стека на повикванията“.

— Но ти каза, че програмата не винаги се прекратява.

„Да, защото има начин да хванем изключение. Можем да напишем специален code на правилното място, за да хванем изключенията, които ни интересуват, и да направим нещо с тях. Това са важни неща.“

„За да ни помогне да направим това, има специална конструкция try-catch . Ето How работи:“

Пример за програма, която хваща изключение (деление на 0) и продължава да работи.
public class ExceptionExample2
{
    public static void main(String[] args)
    {
        System.out.println("Program starts");

        try
        {
            System.out.println("Before calling method1");
            method1();
            System.out.println("After calling method1. This will never 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);
    }
}
Изход на екрана:
Program starts
Before method1 calling
Exception has been caught
Program is still running

„Но защо на екрана не се показва „След извикване на метод1. Това никога няма да се покаже“?“

„Радвам се, че попитахте. В ред 25 делим на 0, което води до грешка – изключение. Java машината създава обект ArithmeticException с информация за грешката. Обектът е изключение.“

"Изключението възниква вътре в method1метода. Това води до незабавно прекратяване на метода. Това би довело до прекратяване на основния метод, ако не беше блокът try-catch ."

"Ако възникне изключение вътре в блок try , то се улавя в блока catch . Останалата част от codeа в блока try няма да бъде изпълнена. Вместо това блокът catch ще започне да се изпълнява. "

— Не разбирам.

„С други думи, codeът работи по следния начин:

1. Ако възникне изключение в блок try , codeът престава да се изпълнява там, където е възникнало изключението, и блокът catch започва да се изпълнява.

2. Ако не възникне изключение, блокът try се изпълнява докрай , а блокът catch не се изпълнява. "

"А?"

„Представете си, че след всяко извикване на метод проверяваме дали методът се е върнал нормално or е внезапно прекратен в резултат на изключение. Ако има изключение, тогава преминаваме към изпълнение на catch блока (ако има такъв), за да уловим изключението. Ако няма catch блок, тогава прекратяваме текущия метод и методът, който ни е извикал, извършва същата проверка."

— Мисля, че вече го разбрах.

"Отлично."

„Какво означава „Изключение“ в оператора catch?“

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

"Страхотно! Ако в моя метод се появят различни изключения, тогава мога ли да ги обработя по различен начин?"

„Не само можете, но и трябва. Можете да направите това по следния начин:“

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

        try
        {
            System.out.println("Before calling method1");
            method1();
            System.out.println("After calling method1. This will never be shown");
        }
        catch (NullPointerException e)
        {
           System.out.println("Null reference. 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 блока, всеки от които ще улови определените типове изключения.“

„Мисля, че разбирам. Все още не мога да напиша това сам, но ако го попадна в code, няма да се уплаша.“