חריגים נפוצים של Java

1. הקדמה

מדריך זה מתמקד בכמה חריגים נפוצים של Java.

נתחיל בדיון מהו חריג בעצם. בהמשך נדון בפירוט בסוגים שונים של חריגים מסומנים ולא מסומנים.

2. חריגים

יוצא מן הכלל הוא מצב לא תקין המתרחש ברצף קוד במהלך ביצוע התוכנית. מצב לא תקין זה נוצר כאשר תוכנית מפרה אילוצים מסוימים בזמן הריצה.

כל סוגי החריגים הם מחלקות משנה של הכיתה יוצא מן הכלל. אז מחלקה מחלקה זו לחריגים מסומנים ולחריגים לא מסומנים. אנו נשקול אותם בפירוט בסעיפים הבאים.

3. חריגים מסומנים

חריגים מסומנים הם חובה לטפל בהם. הם מחלקות משנה ישירות של הכיתה יוצא מן הכלל.

יש ויכוח על חשיבותם שכדאי להעיף מבט.

בואו נגדיר בפירוט כמה יוצאים מן הכלל.

3.1. IOException

שיטה זורקת IOException או תת-מחלקה ישירה שלו כאשר פעולת קלט / פלט כלשהי נכשלת.

שימושים אופייניים לפעולות קלט / פלט אלה כוללים:

  • עבודה עם מערכת הקבצים או זרמי הנתונים באמצעות java.io חֲבִילָה
  • יצירת יישומי רשת באמצעות java.net חֲבִילָה

FileNotFoundException

FileNotFoundException הוא סוג נפוץ של IOException תוך כדי עבודה עם מערכת הקבצים:

נסה {new FileReader (קובץ חדש ("/ לא חוקי / קובץ / מיקום")); } לתפוס (FileNotFoundException e) {LOGGER.info ("FileNotFoundException נתפס!"); }

פגום urlexception

כשעובדים עם כתובות אתרים, אנו עשויים להיתקל ב פגום urlexception - אם כתובות האתרים שלנו אינן חוקיות.

נסה {URL חדש ("malformedurl"); } לתפוס (MalformedURLException e) {LOGGER.error ("MalformedURLException נתפס!"); }

3.2. ParseException

Java משתמשת בניתוח טקסטים ליצירת אובייקט המבוסס על נתון חוּט.אם הניתוח גורם לשגיאה, הוא זורק a ParseException.

למשל, נוכל לייצג תַאֲרִיך בדרכים שונות למשל dd / mm / yyyy אוֹ dd, mm, yyyy, אבל נסה לנתח א חוּט עם פורמט אחר:

נסה את {new SimpleDateFormat ("MM, dd, yyyy"). ניתוח ("תאריך לא חוקי"); } לתפוס (ParseException e) {LOGGER.error ("ParseException נתפס!"); }

הנה ה חוּט לקוי וגורם ל ParseException.

3.3. חריג מופרע

בכל פעם ששרשור Java מתקשר להצטרף (), לישון () אוֹ לַחֲכוֹת() זה נכנס לתוכנת הַמתָנָה המדינה או TIMED_WAITING מדינה.

בנוסף, חוט יכול להפריע לשרשור אחר על ידי קריאה לשרשור אחר פסיקת() שיטה.

כתוצאה מכך, ה חוט זורק חריג מופרע אם חוט אחר קוטע אותו בזמן שהוא נמצא ב הַמתָנָה או ב TIMED_WAITING מדינה.

שקול את הדוגמה הבאה עם שני שרשורים:

  • החוט הראשי מתחיל את חוט הילד וקוטע אותו
  • חוט הילד מתחיל ומתקשר לִישׁוֹן()

תרחיש זה מביא לתוצאה חריג מופרע:

מחלקה ChildThread מרחיב אשכול {הפעלה בטלנית () (נסה {Thread.sleep (1000); } לתפוס (InterruptedException ה) {LOGGER.error ("InterruptedException שנתפס!"); }}} מחלקה ציבורית MainThread {public static void main (String [] args) זורק InterruptedException {ChildThread childThread = ChildThread חדש (); childThread.start (); childThread.interrupt (); }}

4. חריגים לא מסומנים

עבור חריגים לא מסומנים, המהדר לא בודק במהלך תהליך האוסף. לפיכך, אין חובה שהשיטה תטפל בחריגים אלה.

כל החריגים הלא מסומנים מרחיבים את הכיתה חריגת זמן ריצה.

בואו נדון בפירוט בכמה יוצאים מן הכלל.

4.1. NullPointerException

אם יישום מנסה להשתמש ריק איפה שזה באמת דורש מופע של אובייקט, השיטה תזרוק a NullPointerException.

ישנם תרחישים שונים בהם השימושים הבלתי חוקיים של ריק גורם ל NullPointerException. בואו ניקח בחשבון כמה מהם.

קריאה לשיטה של ​​הכיתה שאין לה מופע אובייקט:

מחרוזת strObj = null; strObj.equals ("שלום עולם"); // זורק את NullPointerException.

כמו כן, אם יישום מנסה לגשת או לשנות משתנה מופע עם ריק התייחסות, אנו מקבלים א NullPointerException:

אדם אדםObj = null; שם מחרוזת = personObj.personName; // גישה לשדה של אדם אובייקט ריק nullbj.personName = "ג'ון דו"; // שינוי שדה של אובייקט null

4.2. אינדקס מערך מחוץ לתחום Exception

מערך מאחסן את האלמנטים שלו באופן רציף. לפיכך, אנו יכולים לגשת לאלמנטים שלה באמצעות מדדים.

למרות זאת, אם פיסת קוד מנסה לגשת לאינדקס לא חוקי של מערך, השיטה המתאימה זורקת ArrayIndexOutOfBoundException.

בואו נראה כמה דוגמאות שזורקות ArrayIndexOutOfBoundException:

int [] nums = int int [] {1, 2, 3}; int numFromNegativeIndex = nums [-1]; // מנסה לגשת לאינדקס שלילי int numFromGreaterIndex = nums [4]; // מנסה לגשת לאינדקס גדול יותר int numFromLengthIndex = nums [3]; // מנסה לגשת לאינדקס השווה לגודל המערך

4.3. StringIndexOutOfBoundsException

ה חוּט מחלקה ב- Java מספקת את השיטות לגישה לדמות מסוימת של המחרוזת או לפרוס מערך תווים מתוך ה- חוּט. כאשר אנו משתמשים בשיטות אלה, באופן פנימי הוא ממיר את ה- חוּט לתוך מערך דמויות.

שוב, יכול להיות שיש שימוש לא חוקי באינדקסים במערך זה. במקרים כאלה, שיטות אלה של חוּט הכיתה זורקת את StringIndexOutOfBoundsException.

חריג זה מציין שהמדד גדול או שווה לגודל ה- חוּט.StringIndexOutOfBoundsException מרחיב IndexOutOfBoundsException.

השיטה charAt (אינדקס) של הכיתה חוּט זורק חריג זה כאשר אנו מנסים לגשת לדמות באינדקס השווה ל- מחרוזת אורך או אינדקס לא חוקי אחר:

מחרוזת str = "שלום עולם"; char charAtNegativeIndex = str.charAt (-1); // מנסה לגשת למדד השלילי char charAtLengthIndex = str.charAt (11); // מנסה לגשת לאינדקס השווה לגודל המחרוזת 

4.4. NumberFormatException

לעתים קרובות למדי יישום מסתיים עם נתונים מספריים ב- חוּט. על מנת לפרש נתונים אלה כמספריים, ג'אווה מאפשרת המרה של חוּט לסוגים מספריים. שיעורי העטיפה כגון שלם, צף וכו '. מכיל שיטות שימוש למטרה זו.

למרות זאת, אם ה חוּט אין פורמט מתאים במהלך ההמרה, השיטה זורקת a NumberFormatException.

בואו ניקח בחשבון את הקטע הבא.

הנה, אנו מכריזים על א חוּט עם נתונים אלפאנומריים. יתר על כן, אנו מנסים להשתמש בשיטות ה- מספר שלם מחלקת עטיפה כדי לפרש נתונים אלה כמספריים.

כתוצאה מכך, התוצאה היא NumberFormatException:

מחרוזת str = "100ABCD"; int x = Integer.parseInt (str); // זורק NumberFormatException int y = Integer.valueOf (str); // זורק NumberFormatException

4.5. חישוב חשבון

כאשר תוכנית מעריכה פעולת חשבון והיא גורמת למצב חריג כלשהו, ​​היא זורקת חישוב חשבון. בנוסף, חישוב חשבון חל רק על int ו ארוך סוגי מידע.

למשל, אם ננסה לחלק מספר שלם באפס, נקבל חישוב חשבון:

לא חוקי פעולה = 30/0; // זורק חישוב אריתמטי

4.6. ClassCastException

ג'אווה מאפשרת הדפסת שורות בין האובייקטים על מנת לתמוך בירושה ופולימורפיזם. אנחנו יכולים להפיל את האובייקט או להפיל אותו.

בשידור מעלה אנו מטילים אובייקט לסוג העל שלו. ובהנפילה, אנו מטילים אובייקט על אחד מתתי-הסוגים שלו.

למרות זאת, בזמן הריצה, אם הקוד מנסה להוריד אובייקט לתת-סוג שהוא אינו מופע, השיטה זורקת ClassCastException.

מופע זמן הריצה הוא מה שחשוב בפועל בהקלטות טיפוסי. שקול את הירושה הבאה בין בעל חיים, כלב ואריה:

class Animal {} class Dog extends Animal {} class Lion extends Animal {} 

יתר על כן, בכיתת הנהגים, אנחנו מטילים את בעל חיים הפניה המכילה מופע של אַריֵה לתוך כֶּלֶב.

עם זאת, בזמן הריצה, ה- JVM שם לב למופע זה אַריֵה אינו תואם לסוג המשנה של הכיתה כֶּלֶב.

זו התוצאה ClassCastException:

בעל חיים = אריה חדש (); // בזמן הריצה המופע הוא כלב האריה טומי = (כלב) בעל חיים; // זורק ClassCastException

4.7. IllegalArgumentException

שיטה זורקת IllegalArgumentException אם נקרא לזה בכמה וויכוחים לא חוקיים או בלתי הולמים.

למשל, ה לִישׁוֹן() שיטת ה- פְּתִיל הכיתה מצפה לזמן חיובי ואנחנו מעבירים מרווח זמן שלילי כוויכוח. זו התוצאה IllegalArgumentException:

Thread.currentThread (). שינה (-10000); // זורק חריג לא חוקי

4.8. IllegalStateException

IllegalStateException מסמן כי שיטה הופעלה בזמן בלתי חוקי או בלתי הולם.

לכל אובייקט Java יש מצב (משתני מופע) והתנהגות כלשהי (שיטות). לכן, IllegalStateException פירושו שזה לא חוקי להפעיל את ההתנהגות של אובייקט זה עם משתני המצב הנוכחיים.

עם זאת, עם כמה משתני מצב שונים, זה עשוי להיות חוקי.

לדוגמא, אנו משתמשים באיטרטור כדי לחזור על רשימה. בכל פעם שאנחנו מאתחלים אחד, הוא מגדיר באופן פנימי את משתנה המצב שלו lastRet ל -1.

בהקשר זה, התוכנית מנסה לקרוא ל- לְהַסִיר שיטה ברשימה:

// מאותחל עם אינדקס ב -1 Iterator intListIterator = ArrayList חדש (). Iterator (); intListIterator.remove (); // IllegalStateException 

באופן פנימי, לְהַסִיר השיטה בודקת את משתנה המצב lastRet ואם זה פחות מ 0, זה זורק IllegalStateException. כאן, המשתנה עדיין מצביע על הערך -1.

כתוצאה מכך, אנו מקבלים IllegalStateException.

5. מסקנה

במאמר זה דנו לראשונה בחריגים. An יוצא מן הכלל הוא אירוע המתרחש במהלך ביצוע התוכנית המשבש את הזרימה הרגילה של הוראות התוכנית.

לאחר מכן, סיווגנו את החריגים לחריגים מסומנים ולחריגים לא מסומנים.

לאחר מכן, דנו בסוגים שונים של חריגים שיכולים לעלות בזמן הקומפילציה או בזמן הריצה.

אנו יכולים למצוא את הקוד עבור מאמר זה ב- GitHub.