CodeGym /Java блог /Случаен /Изключения в Java
John Squirrels
Ниво
San Francisco

Изключения в Java

Публикувано в групата
Здравейте! В днешния урок ще говорим за Java Exceptions. Ежедневието е пълно със ситуации, които не очакваме. Например ставате сутрин за работа и търсите зарядното за телефона си, но не можете да го намерите никъде. Отивате до банята, за да се изкъпете, само за да откриете, че тръбите са замръзнали. Качваш се в колата си, но тя не иска да запали. Човек може лесно да се справи с подобни непредвидени обстоятелства. В тази статия ще се опитаме да разберем How Java програмите се справят с тях.

Какво е изключение на Java?

В света на програмирането грешките и непредвидените ситуации при изпълнението на програма се наричат ​​изключения. В дадена програма могат да възникнат изключения поради невалидни потребителски действия, недостатъчно дисково пространство or загуба на мрежова връзка със сървъра. Изключенията могат също да са резултат от програмни грешки or неправилно използване на API. За разлика от хората в реалния свят, програмата трябва да знае точно How да се справи с тези ситуации. За това Java има механизъм, известен като обработка на изключения.

Няколко думи за ключовите думи

Обработката на изключения в Java се основава на използването на следните ключови думи в програмата:
  • опитайте - дефинира блок от code, където може да възникне изключение;
  • catch - дефинира блок от code, където се обработват изключения;
  • finally - дефинира незадължителен блок от code, който, ако присъства, се изпълнява независимо от резултатите от блока try.
Тези ключови думи се използват за създаване на специални конструкции в codeа: try{}catch , try{}catch{}finally , try{}finally{} .
  • throw - използва се за предизвикване на изключение;
  • throws - използва се в сигнатурата на метода, за да предупреди, че методът може да хвърли изключение.
Пример за използване на ключови думи в Java програма:

// This method reads a string from the keyboard

public String input() throws MyException { // Use throws to warn 
// that the method may throw a MyException
      BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = null;
// We use a try block to wrap code that might create an exception. In this case,
// the compiler tells us that the readLine() method in the 
// BufferedReader class might throw an I/O exception
    try {
        s = reader.readLine();
// We use a catch block to wrap the code that handles an IOException  
    } catch (IOException e) {
        System.out.println(e.getMessage());
// We close the read stream in the finally block
    } finally {
// An exception might occur when we close the stream if, for example, the stream was not open, so we wrap the code in a try block
        try {
            reader.close();
// Handle exceptions when closing the read stream
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

    if (s.equals("")) {
// We've decided that an empty string will prevent our program from working properly. For example, we use the result of this method to call the substring(1, 2) method. Accordingly, we have to interrupt the program by using throw to generate our own MyException exception type.
        throw new MyException("The string cannot be empty!");
    }
    return s;
}

Защо имаме нужда от изключения?

Нека да разгледаме пример от реалния свят. Представете си, че участък от магистрала има малък мост с ограничена товароносимост. Ако кола, по-тежка от ограничението на моста, мине по него, той може да се срути. Ситуацията за водача би станала меко казано изключителна. За да избегне това, транспортният отдел инсталира предупредителни знаци на пътя, преди нещо да се обърка. Виждайки предупредителния знак, водачът сравнява теглото на автомобила си с максималното тегло за моста. Ако превозното средство е твърде тежко, водачът избира обходен маршрут. Транспортният отдел, първо, даде възможност на шофьорите на камиони да променят маршрута си, ако е необходимо, второ, предупреди шофьорите за опасностите по главния път и трето, предупреди шофьорите, че мостът не трябва да се използва при определени условия. Изключения в Java - 2Способността да се предотвратяват и разрешават изключителни ситуации в програма, позволявайки й да продължи да работи, е една от причините за използването на изключения в Java. Механизмът за изключение също ви позволява да защитите вашия code (API) от неправилна употреба чрез валидиране (проверка) на всички входове. Сега си представете, че сте транспортният отдел за секунда. Първо, трябва да знаете местата, където шофьорите могат да очакват проблеми. Второ, трябва да създадете и инсталирате предупредителни знаци. И накрая, трябва да осигурите обходни маршрути, ако възникнат проблеми по главния маршрут. В Java механизмът за изключение работи по подобен начин. По време на разработката използваме блок за опит , за да изградим „бариери за изключения“ около опасни участъци от codeа, предоставяме „резервни маршрути“, използвайки уловка {}блок и ние пишем code, който трябва да се изпълнява независимо Howво в блок finally{} . Ако не можем да предоставим „резервен маршрут“ or искаме да дадем на потребителя право на избор, трябва поне да го предупредим за опасността. Защо? Представете си само възмущението на шофьор, който без да види нито един предупредителен знак, стига до малко мостче, по което не може да премине! В програмирането, когато пишем нашите класове и методи, не винаги можем да предвидим How те могат да бъдат използвани от други разработчици. В резултат на това не можем да предвидим 100% правилния начин за разрешаване на извънредна ситуация. Въпреки това е добра форма да предупредите другите за възможността от извънредни ситуации. Механизмът за изключение на Java ни позволява да правим това с хвърляниятаключова дума — по същество декларация, че общото поведение на нашия метод включва хвърляне на изключение. По този начин всеки, който използва метода, знае, че трябва да пише code за обработка на изключения.

Предупреждаване на другите за „проблеми“

Ако не планирате да обработвате изключения във вашия метод, но искате да предупредите другите, че могат да възникнат изключения, използвайте ключовата дума throws . Тази ключова дума в сигнатурата на метода означава, че при определени условия методът може да хвърли изключение. Това предупреждение е част от интерфейса на метода и позволява на неговите потребители да реализират своя собствена логика за обработка на изключения. След хвърлянията ние указваме типовете хвърлени изключения. Те обикновено произлизат от класа Exception на Java . Тъй като Java е обектно-ориентиран език, всички изключения са обекти в Java. Изключения в Java - 3

Йерархия на изключенията

Когато възникне грешка по време на изпълнение на програма, JVM създава обект от подходящия тип от йерархията на изключенията на Java – набор от възможни изключения, които произлизат от общ предшественик – класът Throwable . Можем да разделим изключителните ситуации по време на изпълнение на две групи:
  1. Ситуации, от които програмата не може да се възстанови и да продължи нормалната си работа.
  2. Ситуации, при които е възможно възстановяване.
Първата група включва ситуации, включващи изключение, което произлиза от класа Error . Това са грешки, които възникват поради неизправност на JVM, препълване на паметта or повреда на системата. Те обикновено показват сериозни проблеми, които не могат да бъдат отстранени от софтуера. В Java възможността за такива изключения не се проверява от компилатора, така че те са известни като непроверени изключения. Тази група включва също RuntimeExceptions, които са изключения, произлизащи от Exceptionклас и се генерират от JVM по време на изпълнение. Те често са причинени от програмни грешки. Тези изключения също не се проверяват (не се проверяват) по време на компorране, така че не се изисква да пишете code, който да ги обработва. Втората група включва изключителни ситуации, които могат да бъдат предвидени, когато пишете програмата (и следователно трябва да напишете code, за да се справите с тях). Такива изключения се наричат ​​проверени изключения. Когато става въпрос за изключения, по-голямата част от работата на разработчика на Java е справяне с такива ситуации.

Създаване на изключение

Когато една програма се изпълнява, изключенията се генерират or от JVM, or ръчно с помощта на израз за хвърляне . Когато това се случи, обект на изключение се създава в паметта, главният поток на програмата се прекъсва и манипулаторът на изключения на JVM се опитва да обработи изключението.

Обработка на изключения

В Java създаваме codeови блокове, където предвиждаме необходимостта от обработка на изключения с помощта на конструкциите try{}catch , try{}catch{}finally и try{}finally{} . Изключения в Java - 4Когато изключение бъде хвърлено в блок try , JVM търси подходящ манипулатор на изключения в следващия блок catch . Ако catch блок има необходимия манипулатор на изключения, контролът преминава към него. Ако не, тогава JVM търси по-надолу по веригата от catch блокове, докато бъде намерен подходящият манипулатор. След изпълнение на catch блок, управлението се прехвърля към незадължителния finally блок. Ако подходящ уловблокът не е намерен, тогава JVM спира програмата и показва проследяването на стека (текущия стек от извиквания на метод), след като първо изпълни блока finally , ако съществува. Пример за обработка на изключение:

public class Print {

     void print(String s) {
        if (s == null) {
            throw new NullPointerException("Exception: s is null!");
        }
        System.out.println("Inside print method: " + s);
    }

    public static void main(String[] args) {
        Print print = new Print();
        List list= Arrays.asList("first step", null, "second step");

        for (String s : list) {
            try {
                print.print(s);
            }
            catch (NullPointerException e) {
                System.out.println(e.getMessage());
                System.out.println("Exception handled. The program will continue");
            }
            finally {
                System.out.println("Inside finally block");
            }
            System.out.println("The program is running...");
            System.out.println("-----------------");
        }

    }
    }
Ето резултатите от основния метод:

Inside print method: first step
Inside finally block
The program is running...
-----------------
Exception: s is null!
Exception handled. The program will continue
Inside finally block
The program is running...
-----------------
Inside print method: second step
Inside finally block
The program is running...
-----------------
Finally обикновено се използва за затваряне на всички потоци и освобождаване на всички ресурси, отворени/разпределени в блок try . Въпреки това, когато пишете програма, не винаги е възможно да следите затварянето на всички ресурси. За да улеснят живота ни, разработчиците на Java предлагат конструкцията try-with-resources , която автоматично затваря всички ресурси, отворени в блок try . Първият ни пример може да бъде пренаписан с try-with-resources :

public String input() throws MyException {
    String s = null;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))){
        s = reader.readLine();
   } catch (IOException e) {
       System.out.println(e.getMessage());
   }
    if (s.equals("")) {
        throw new MyException ("The string cannot be empty!");
    }
    return s;
}
Благодарение на възможностите на Java, въведени във version 7, можем също така да комбинираме прихващането на разнородни изключения в един блок, което прави codeа по-компактен и четим. Пример:

public String input() {
    String s = null;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
        s = reader.readLine();
        if (s.equals("")) {
            throw new MyException("The string cannot be empty!");
        }
    } catch (IOException | MyException e) {
        System.out.println(e.getMessage());
    }
    return s;
}

Долния ред

Използването на изключения в Java ви позволява да направите програмите си по-стабилни чрез създаване на „резервни маршрути“, използване на catch блокове, за да отделите основния code от codeа за обработка на изключения, и използване на хвърляния, за да прехвърлите отговорността за обработката на изключения към всеки, който използва вашия метод.
Коментари
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION