JavaRush /בלוג Java /Random-HE /חריגים והטיפול בהם
articles
רָמָה

חריגים והטיפול בהם

פורסם בקבוצה
חריגים או מצבים חריגים (מצבים) הם שגיאות המתרחשות בתוכנית במהלך פעולתה. כל החריגים ב-Java הם אובייקטים. לכן, הם יכולים להיווצר לא רק באופן אוטומטי כאשר מתרחש מצב חריג, אלא גם ליצור על ידי המפתח עצמו. היררכיה של מחלקות חריגות: Исключения и их обработка - 1חריגים מחולקים למספר מחלקות, אך לכולם יש אב קדמון משותף - המחלקה Throwable. צאצאיו הם תת המחלקות Exceptionו Error. חריגים ( Exceptions) הם תוצאה של בעיות בתוכנית שהן, באופן עקרוני, ניתנות לפתרון וניתנות לחיזוי. לדוגמה, החלוקה באפס התרחשה במספרים שלמים. שגיאות ( Errors) הן בעיות חמורות יותר שמפרט Java קובע שאסור לך לנסות לטפל בהן בתוכנית שלך מכיוון שהן בעיות ברמת JVM. לדוגמה, חריגים מסוג זה מתרחשים אם הזיכרון הזמין למכונה הוירטואלית אזל. התוכנית עדיין לא תוכל לספק זיכרון נוסף עבור ה-JVM. ב-Java, כל החריגים מחולקים לשלושה סוגים: חריגים מסומנים ( checked) וחריגים לא מסומנים ( unchecked) הכוללים שגיאות ( Errors) וחריגים בזמן ריצה ( RuntimeExceptionsצאצא מחלקה Exception). חריגים מבוקרים הם שגיאות שניתן וצריך לטפל בהן בתוכנית; כל הצאצאים של מחלקה Exception(אך לא RuntimeException) שייכים לסוג זה. טיפול בחריגים יכול להתבצע באמצעות אופרטורים try…catchאו להעביר לחלק החיצוני של התוכנית. לדוגמה, שיטה יכולה להעביר חריגים המתרחשים בה גבוה יותר בהיררכיית השיחות מבלי לטפל בה בעצמה. חריגים לא מסומנים אינם דורשים טיפול, אבל אתה יכול לטפל בחריגים בכיתה אם תרצה RuntimeException. בואו נקמפל ונפעיל את התוכנית הבאה:
class Main {
     public static void main(String[] args) {
         int a = 4;
         System.out.println(a/0);
     }
}
בעת ההשקה, ההודעה הבאה תוצג במסוף:
Exception in thread "main" java.lang.ArithmeticException: / by zero
        at Main.main(Main.java:4)
ההודעה מציגה את המחלקה של החריג שהתרחש - ArithmeticException. ניתן לטפל בחריג זה:
class Main {
     public static void main(String[] args) {
         int a = 4;
         try {
              System.out.println(a/0);
         } catch (ArithmeticException e) {
              System.out.println("Произошла недопустимая арифметическая операция");
         }
     }
}
כעת, במקום הודעת שגיאה רגילה, יבוצע בלוק catch, שהפרמטר שלו הוא האובייקט e של המחלקה המתאים לחריג (ניתן לתת לאובייקט עצמו כל שם, הוא נחוץ אם נרצה לזרוק בכוח החריג הזה שוב, למשל, כדי שהוא ייבדק באיזה מטפל אחר). במקרה זה, הבלוק tryמכיל את קטע התוכנית שבו עלול להתרחש חריג. אפשר tryלהתאים למספר בלוקים של תפיסה עם מחלקות חריגות שונות.
import java.util.Scanner;
class Main {
    public static void main(String[] args) {
     int[] m = {-1,0,1};
        Scanner sc = new Scanner(System.in);
        try {
            int a = sc.nextInt();
            m[a] = 4/a;
            System.out.println(m[a]);
        } catch (ArithmeticException e) {
            System.out.println("Произошла недопустимая арифметическая операция");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Обращение по недопустимому индексу массива");
        }
    }
}
Если запустив представленную программу, пользователь введётся с клавиатуры 1 or 2, то программа отработает без создания Howих-либо исключений. Если пользователь введёт 0, то возникнет исключение класса ArithmeticException, и оно будет обработано первым блоком catch. Если пользователь введёт 3, то возникнет исключение класса ArrayIndexOutOfBoundsException (выход за приделы массива), и оно будет обработано вторым блоком catch. Если пользователь введёт нецелое число, например, 3.14, то возникнет исключение класса InputMismatchException (несоответствие типа вводимого meaning), и оно будет выброшено в формате стандартной ошибки, поскольку его мы ниHow не обрабатывали. Можно, однако, добавить обработчик для класса Exception, поскольку этот класс родительский для всех остальных контролируемых исключений, то он будет перехватывать любые из них (в том числе, и InputMismatchException).
import java.util.Scanner;
class Main {
    public static void main(String[] args) {
        int[] m = {-1,0,1};
        int a = 1;
        Scanner sc = new Scanner(System.in);
        try {
            a = sc.nextInt();
            m[a-1] = 4/a;
            System.out.println(m[a]);
        } catch (ArithmeticException e) {
            System.out.println("Произошла недопустимая арифметическая операция");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Обращение по недопустимому индексу массива");
        } catch (Exception e) {
            System.out.println("Произошло ещё Howое-то исключение");
        }
    }
}
Поскольку исключения построены на иерархии классов и подклассов, то сначала надо пытаться обработать более частные исключения и лишь затем более общие. То есть поставив первым (а не третьим) блок с обработкой исключения класса Exception, мы бы никогда не увидели ниHowих сообщений об ошибке, кроме «Произошло ещё Howое-то исключение» (все исключения перехватorсь бы сразу этим блоком и не доходor бы до остальных). Необязательным добавлением к блокам try…catch может быть блок finally. Помещенные в него команды будут выполняться в любом случае, вне зависимости от того, произошло ли исключение or нет. При том, что при возникновении необработанного исключения оставшаяся после генерации этого исключения часть программы — не выполняется. Например, если исключение возникло в процессе Howих-то длительных вычислений, в блоке finally можно показать or сохранить промежуточные результаты. Ссылка на первоисточник: Исключения и их обработка
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION