"สวัสดี Amigo เราจะมีบทเรียนที่น่าสนใจมากในวันนี้ ฉันจะบอกคุณเกี่ยวกับข้อยกเว้นข้อยกเว้นเป็นกลไกพิเศษที่ช่วยให้เราจัดการกับข้อผิดพลาดในโปรแกรมนี่คือตัวอย่างบางส่วนของข้อผิดพลาดที่อาจเกิดขึ้น ในโปรแกรม:

1. โปรแกรมอาจพยายามเขียนไฟล์เมื่อฮาร์ดไดรฟ์เต็ม

2. โปรแกรมอาจพยายามเรียกใช้เมธอดบนตัวแปรที่จัดเก็บการอ้างอิงค่าว่าง

3. โปรแกรมอาจพยายามหารตัวเลขด้วย 0"

การกระทำทั้งหมดเหล่านี้ส่งผลให้เกิดข้อผิดพลาด โดยปกติแล้วผลลัพธ์คือโปรแกรมจะหยุดทำงานทันทีเนื่องจากไม่สมเหตุสมผลที่จะดำเนินการโค้ดต่อไปในกรณีนี้

"ทำไม?"

"มันสมเหตุสมผลไหมที่จะหมุนล้อต่อไปหากรถหลุดออกจากถนนและตกจากหน้าผา"

"โปรแกรมควรหยุดทำงานหรือไม่"

"ใช่ อย่างน้อยนี่คือสิ่งที่เคยเกิดขึ้นข้อผิดพลาดใด ๆ ที่ทำให้โปรแกรมยุติลง"

"นั่นเป็นวิธีที่ฉลาดมาก"

“แต่จะดีกว่าไหมถ้าลองรันโปรแกรมต่อไป?”

"ใช่ สมมติว่าคุณพิมพ์ข้อความจำนวนมากใน Word และบันทึกไว้ จะทำอย่างไรถ้าการบันทึกล้มเหลว แต่โปรแกรมทำให้คุณเชื่อว่าทุกอย่างปกติดี? และคุณพิมพ์ต่อไป นั่นคงโง่ คงไม่ มัน?"

"ใช่."

"จากนั้นโปรแกรมเมอร์ก็คิดวิธีแก้ปัญหาที่น่าสนใจแต่ละฟังก์ชันจะส่งกลับสถานะของงาน 0 หมายความว่าทำงานตามที่คาดไว้ ค่าอื่น ๆ จะหมายความว่ามีข้อผิดพลาดเกิดขึ้น และค่าส่งกลับเป็นรหัสข้อผิดพลาด"

"อย่างไรก็ตาม แนวทางดังกล่าวก็มีข้อบกพร่องเช่นกัน หลังจากการเรียกใช้ฟังก์ชัน (!) ทุกครั้ง คุณต้องตรวจสอบโค้ดส่งคืน (หมายเลข) ประการแรก การดำเนินการนี้ไม่สะดวก: โค้ดการจัดการข้อผิดพลาดมักไม่ค่อยได้ดำเนินการ แต่จำเป็นต้องรวมไว้ด้วย ทุกที่ ประการที่สอง ฟังก์ชันต่างๆ มักจะส่งคืนค่าต่างๆ กัน คุณจะทำอย่างไรกับค่าเหล่านี้"

"ใช่ ฉันก็คิดถึงเรื่องนั้นเหมือนกัน"

"จากนั้น อนาคตที่สดใสก็มาถึงในรูปแบบของข้อยกเว้นและกลไกจัดการข้อผิดพลาด นี่คือวิธีการทำงาน:

1. เมื่อเกิดข้อผิดพลาด Java Machine จะสร้างวัตถุพิเศษ – ข้อยกเว้น – ซึ่งจะบันทึกข้อมูลข้อผิดพลาดทั้งหมด มีข้อยกเว้นที่แตกต่างกันสำหรับข้อผิดพลาดที่แตกต่างกัน

2. ข้อยกเว้นทำให้โปรแกรมออกจากฟังก์ชันปัจจุบันและฟังก์ชันถัดไป และอื่นๆ ทันที จนกว่าจะออกจากเมธอดหลัก จากนั้นโปรแกรมจะสิ้นสุดลง โปรแกรมเมอร์อาจกล่าวได้ว่า Java Machine 'คลาย call stack'"

“แต่คุณบอกว่าโปรแกรมไม่ได้จบลงเสมอไป”

"ใช่ เพราะมีวิธีจับข้อยกเว้นเราสามารถเขียนโค้ดพิเศษในตำแหน่งที่เหมาะสมเพื่อจับข้อยกเว้นที่เราสนใจและทำบางอย่างกับพวกมันได้ นี่เป็นสิ่งสำคัญ"

"เพื่อช่วยให้เราทำสิ่งนี้ มี โครงสร้าง try-catch พิเศษ นี่คือวิธีการทำงาน:"

ตัวอย่างของโปรแกรมที่ตรวจจับข้อยกเว้น (หารด้วย 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

"แต่ทำไม 'หลังจากเรียก method1. สิ่งนี้จะไม่แสดง' ปรากฏขึ้นบนหน้าจอ"

"ฉันดีใจที่คุณถาม ในบรรทัดที่ 25 เราหารด้วย 0 ซึ่งนำไปสู่ข้อผิดพลาด – ข้อยกเว้น Java Machine สร้างวัตถุArithmeticExceptionพร้อมข้อมูลเกี่ยวกับข้อผิดพลาด วัตถุนั้นเป็นข้อยกเว้น"

"ข้อยกเว้นเกิดขึ้นภายในmethod1เมธอดซึ่งทำให้เมธอดยุติทันทีมันจะทำให้เมธอดหลัก ยุติหากไม่ใช่เพราะบล็อก try-catch "

"หากมีข้อยกเว้นเกิดขึ้นภายใน บล็อก try ข้อผิดพลาด นั้นจะติดอยู่ในบล็อกcatch โค้ดที่เหลือในบล็อก try จะไม่ถูกดำเนินการ แต่ บล็อก catchจะเริ่มดำเนินการแทน "

"ฉันไม่เข้าใจ"

"กล่าวอีกนัยหนึ่ง รหัสทำงานดังนี้:

1. หากมีข้อยกเว้นเกิดขึ้นภายใน บล็อก การลองรหัสจะหยุดทำงานเมื่อเกิดข้อยกเว้น และ บล็อก catchจะเริ่มทำงาน

2.หากไม่มีข้อยกเว้นเกิดขึ้น บล็อก try จะถูกดำเนินการจนจบและ บล็อก catchจะไม่ถูกดำเนินการ "

"ฮะ?"

"ลองนึกภาพว่าหลังจากการเรียกใช้เมธอดแต่ละครั้ง เราจะตรวจสอบว่าเมธอดกลับมาเป็นปกติหรือถูกยกเลิกอย่างกะทันหันอันเป็นผลมาจากข้อยกเว้นหรือไม่หากมีข้อยกเว้น เราจะย้ายไปดำเนินการ catch block (หากมี) เพื่อตรวจจับข้อยกเว้นหากไม่มี catch block เราจะยุติเมธอดปัจจุบัน และเมธอดที่เรียกเราทำการตรวจสอบแบบเดียวกัน"

"ฉันคิดว่าฉันได้มันแล้ว"

"ยอดเยี่ยม."

"'ข้อยกเว้น' หมายถึงอะไรในคำสั่ง catch"

" ข้อยกเว้นทั้งหมดคือคลาสที่สืบทอดคลาสข้อยกเว้นเราสามารถตรวจจับข้อยกเว้นเฉพาะได้โดยระบุคลาสข้อยกเว้นใน บล็อก catchหรือเราสามารถตรวจจับข้อยกเว้นทั้งหมดโดยระบุคลาสหลักทั่วไปของคลาสนั้น - ข้อยกเว้น จากนั้นเราจะได้รับข้อผิดพลาดที่จำเป็นทั้งหมด ข้อมูลจากตัวแปร 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บล็อกหลายตัว ซึ่งแต่ละบล็อกจะจับข้อยกเว้นประเภทที่ระบุ"

"ฉันคิดว่าฉันเข้าใจ ฉันยังเขียนสิ่งนี้ด้วยตัวเองไม่ได้ แต่ถ้าฉันเจอมันเป็นโค้ด ฉันก็จะไม่กลัว"