JavaRush /จาวาบล็อก /Random-TH /ข้อยกเว้นใน Java (ข้อยกเว้น Java)

ข้อยกเว้นใน Java (ข้อยกเว้น Java)

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

Java มีข้อยกเว้นอะไรบ้าง

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

สั้น ๆ เกี่ยวกับคำหลัก try, catch, ในที่สุด, พ่น

การจัดการข้อยกเว้นใน Java ขึ้นอยู่กับการใช้คีย์เวิร์ดต่อไปนี้ในโปรแกรม:
  • ลอง - กำหนดบล็อกของโค้ดที่อาจเกิดข้อยกเว้น
  • catch – กำหนดบล็อกของโค้ดที่ใช้จัดการข้อยกเว้น
  • สุดท้าย – กำหนดบล็อกของโค้ดที่เป็นทางเลือก แต่ถ้ามีอยู่ ก็จะดำเนินการต่อไป โดยไม่คำนึงถึงผลลัพธ์ของบล็อกลอง
คำหลักเหล่านี้ใช้เพื่อสร้างโครงสร้างการประมวลผลพิเศษในโค้ดโปรแกรม: try{}catch, try{}catch{}finally, try{}finally{}
  • โยน - ใช้เพื่อยกข้อยกเว้น;
  • พ่น - ใช้ในลายเซ็นวิธีการเพื่อเตือนว่าวิธีการนี้อาจส่งข้อยกเว้น
ตัวอย่างการใช้คีย์เวิร์ดในโปรแกรม Java:
//method reads a string from the keyboard

public String input() throws MyException {//warn with throws,
// that the method can throw MyException
      BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = null;
// in the try block we enclose the code in which an exception can occur, in this
// if the compiler tells us that the readLine() method of the class
// BufferedReader may throw an I/O exception
    try {
        s = reader.readLine();
// in the catch block we enclose the code for handling the IOException exception
    } catch (IOException e) {
        System.out.println(e.getMessage());
// close the read stream in the finally block
    } finally {
// when closing the stream, an exception is also possible, for example, if it was not opened, so we “wrap” the code in a try block
        try {
            reader.close();
// write exception handling when closing the read stream
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

    if (s.equals("")) {
// we decided that an empty string could disrupt the work of our program in the future, for example, on the result of this method, we need to call the substring(1,2) method, so we are forced to interrupt the program execution with the generation of our exception type MyException using throw
        throw new MyException("String can not be empty!");
    }
    return s;
}

เหตุใดเราจึงต้องมีกลไกข้อยกเว้น

ลองดูตัวอย่างในโลกแห่งความเป็นจริง ลองจินตนาการว่ามีส่วนบนทางหลวงที่มีสะพานฉุกเฉินซึ่งมีความจุจำกัด หากยานพาหนะที่มีมวลเกินขีดความสามารถในการรองรับของสะพานขับข้าม สะพานนั้นอาจพังทลาย และสถานการณ์สำหรับผู้ขับขี่อาจพูดง่ายๆ ได้ว่าเป็นเรื่องพิเศษ เพื่อป้องกันไม่ให้เกิดเหตุการณ์เช่นนี้ หน่วยงานบริการทางถนนจึงได้ติดตั้งป้ายเตือนบนถนนไว้ล่วงหน้า ผู้ขับขี่รถยนต์เมื่อดูป้ายเตือนจะเปรียบเทียบน้ำหนักรถกับน้ำหนักที่อนุญาตให้ขับบนสะพานได้ หากเกินกว่านั้นเขาจะอ้อม ต้องขอบคุณการบริการทางถนนที่ทำให้คนขับรถบรรทุกมีโอกาสเปลี่ยนเส้นทางล่วงหน้า ประการที่สอง เตือนอันตรายบนเส้นทางหลัก และสุดท้าย เตือนใช้ไม่ได้ สะพานภายใต้เงื่อนไขบางประการ
Исключения в Java - 2
ความสามารถในการป้องกันและแก้ไขข้อยกเว้นในโปรแกรมเพื่อให้สามารถดำเนินการต่อได้คือหนึ่งในเหตุผลในการใช้ข้อยกเว้นใน Java กลไกข้อยกเว้นยังช่วยให้คุณปกป้องโค้ดที่คุณเขียน (อินเทอร์เฟซการเขียนโปรแกรม) จากการใช้ในทางที่ผิดโดยผู้ใช้โดยการตรวจสอบ (ตรวจสอบ) ข้อมูลขาเข้า ตอนนี้ขอเป็นตำรวจจราจรสักครู่ ขั้นแรกคุณควรทราบสถานที่ที่ผู้ขับขี่รถยนต์อาจประสบปัญหาได้ ประการที่สองต้องเตรียมและติดตั้งป้ายเตือน สุดท้ายต้องจัดให้มีเส้นทางเบี่ยงในกรณีเกิดอันตรายบนเส้นทางหลัก ใน Java กลไกข้อยกเว้นทำงานในลักษณะเดียวกัน ในขั้นตอนการพัฒนาโปรแกรม เราจะ "ปกป้อง" ส่วนที่เป็นอันตรายของโค้ดจากข้อยกเว้นโดยใช้บล็อก try{} จัดเตรียมเส้นทาง "สำรอง" โดยใช้บล็อก catch{} และในบล็อกสุดท้าย {} เราจะเขียนโค้ดที่ถูกเรียกใช้งานใน โปรแกรมสำหรับผลลัพธ์ใด ๆ ในกรณีที่เราไม่สามารถให้ "เส้นทางฉุกเฉิน" หรือจงใจต้องการปล่อยให้ผู้ใช้เลือก อย่างน้อยเราต้องเตือนเขาถึงอันตราย ทำไม ลองนึกภาพความขุ่นเคืองของคนขับที่จะไปถึงสะพานฉุกเฉินที่ไม่สามารถขับข้ามไปได้โดยไม่เจอป้ายเตือนแม้แต่ป้ายเดียวตลอดทาง! ในการเขียนโปรแกรม เมื่อเขียนคลาสและวิธีการของเรา เราไม่สามารถคาดการณ์บริบทการใช้งานโดยนักพัฒนารายอื่นในโปรแกรมของพวกเขาได้เสมอไป ดังนั้นเราจึงไม่สามารถคาดการณ์เส้นทางที่ถูกต้อง 100% เพื่อแก้ไขสถานการณ์ข้อยกเว้นได้ ในเวลาเดียวกัน ถือเป็นแนวปฏิบัติที่ดีที่จะเตือนผู้ใช้เกี่ยวกับโค้ดของเราเกี่ยวกับความเป็นไปได้ที่จะมีข้อยกเว้น กลไกข้อยกเว้นของ Java ช่วยให้เราทำสิ่งนี้ได้โดยใช้การโยน ซึ่งเป็นการประกาศลักษณะการทำงานทั่วไปของวิธีการของเราในการส่งข้อยกเว้น ดังนั้นจึงปล่อยให้ผู้ใช้ใช้วิธีการเขียนโค้ดเพื่อจัดการข้อยกเว้นใน Java

คำเตือนเรื่อง "ปัญหา"

เมื่อคุณไม่ได้วางแผนที่จะจัดการกับข้อยกเว้นในวิธีการของคุณ แต่ต้องการเตือนผู้ใช้ถึงวิธีการเกี่ยวกับสถานการณ์ข้อยกเว้นที่เป็นไปได้ ให้ใช้คีย์เวิร์ด Throws คำสำคัญนี้ในลายเซ็นวิธีการหมายความว่าภายใต้เงื่อนไขบางประการวิธีการนั้นอาจมีข้อยกเว้น คำเตือนนี้เป็นส่วนหนึ่งของอินเทอร์เฟซของวิธีการ และให้สิทธิ์แก่ผู้ใช้ในการปรับแต่งการใช้งานตัวจัดการข้อยกเว้น หลังจากการพ่น เราจะระบุประเภทของข้อยกเว้นที่ถูกโยน โดยปกติแล้วสิ่งเหล่านี้จะ เป็นลูกหลานของ คลาส Java Exception เนื่องจาก Java เป็นภาษาเชิงวัตถุ ข้อยกเว้นทั้งหมดใน Java จึงเป็นวัตถุ
Исключения в Java - 3

ลำดับชั้นข้อยกเว้นของ Java

เมื่อเกิดข้อผิดพลาดระหว่างการทำงานของโปรแกรม รันไทม์ JVM จะสร้างอ็อบเจ็กต์ประเภทที่ต้องการจากลำดับชั้นข้อยกเว้นของ Java ซึ่งเป็นชุดของข้อยกเว้นที่เป็นไปได้ที่สืบทอดมาจาก "บรรพบุรุษ" ทั่วไป - คลาส Throwable สถานการณ์พิเศษที่เกิดขึ้นในโปรแกรมสามารถแบ่งออกเป็นสองกลุ่ม:
  1. สถานการณ์ที่ไม่สามารถฟื้นฟูการทำงานตามปกติของโปรแกรมต่อไปได้
  2. การกู้คืนเป็นไปได้
กลุ่มแรกประกอบด้วยสถานการณ์เมื่อมีข้อยกเว้นที่สืบทอดมาจาก คลาส Error เกิด ขึ้น สิ่งเหล่านี้เป็นข้อผิดพลาดที่เกิดขึ้นระหว่างการทำงานของโปรแกรมอันเป็นผลมาจากความล้มเหลวของ JVM หน่วยความจำล้น หรือระบบล่ม มักจะบ่งบอกถึงปัญหาร้ายแรงที่ไม่สามารถแก้ไขได้โดยใช้ซอฟต์แวร์ ข้อยกเว้นประเภทนี้ใน Java ถูกจัดประเภทเป็นไม่ถูกตรวจสอบในขั้นตอนการคอมไพล์ กลุ่มนี้ยังรวมถึง RuntimeException - ข้อยกเว้น ผู้สืบทอดของ คลาส Exceptionที่สร้างโดย JVM ระหว่างการทำงานของโปรแกรม มักเกิดจากข้อผิดพลาดในการเขียนโปรแกรม ข้อยกเว้นเหล่านี้จะไม่ถูกตรวจสอบในขณะคอมไพล์ ดังนั้นการเขียนโค้ดเพื่อจัดการจึงไม่จำเป็น กลุ่มที่สองประกอบด้วยสถานการณ์พิเศษที่มองเห็นได้ในขั้นตอนของการเขียนโปรแกรมและจะต้องเขียนโค้ดประมวลผล มีการตรวจสอบข้อยกเว้นดังกล่าว งานส่วนใหญ่ของนักพัฒนา Java เมื่อต้องรับมือกับข้อยกเว้นคือการจัดการสถานการณ์ดังกล่าว

การสร้างข้อยกเว้น

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

การจัดการข้อยกเว้น

การสร้างบล็อกโค้ดที่เราจัดให้มีการจัดการข้อยกเว้นใน Java เสร็จสิ้นในโปรแกรมโดยใช้โครงสร้าง try{}catch, try{}catch{}finally, try{}finally{}
Исключения в Java - 4
เมื่อมีการยกข้อยกเว้นขึ้นในบล็อก try ตัวจัดการข้อยกเว้นจะถูกค้นหาในบล็อก catch ต่อไปนี้ หาก catch มีตัวจัดการสำหรับข้อยกเว้นประเภทนี้ การควบคุมจะส่งผ่านไป ถ้าไม่เช่นนั้น JVM จะค้นหาตัวจัดการสำหรับประเภทข้อยกเว้นนั้นในสายการเรียกเมธอดจนกว่าจะพบการจับที่เหมาะสม หลังจากดำเนินการ catch block แล้ว การควบคุมจะถูกส่งผ่านไปยังตัวเลือกบล็อกในที่สุด หากไม่พบบล็อก catch ที่เหมาะสม JVM จะหยุดการทำงานของโปรแกรมและแสดงสแต็กของการเรียกเมธอด - stack Traceโดยก่อนหน้านี้ได้ดำเนินการโค้ดบล็อกสุดท้ายแล้ว ถ้ามี ตัวอย่างการจัดการข้อยกเว้น:
public class Print {

     void print(String s) {
        if (s == null) {
            throw new NullPointerException("Exception: s is null!");
        }
        System.out.println("Inside method print: " + 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 was processed. Program continues");
            }
            finally {
                System.out.println("Inside bloсk finally");
            }
            System.out.println("Go program....");
            System.out.println("-----------------");
        }

    }
    }
ผลลัพธ์ของ วิธีการ หลัก :
Inside method print: first step
Inside bloсk finally
Go program....
-----------------
Exception: s is null!
Exception was processed. Program continues
Inside bloсk finally
Go program....
-----------------
Inside method print: second step
Inside bloсk finally
Go program....
-----------------
โดยปกติแล้ว บล็อกนี้finallyใช้เพื่อปิดสตรีมที่เปิดในบล็อกลองหรือเปิดทรัพยากรให้ว่าง อย่างไรก็ตาม เมื่อเขียนโปรแกรม ไม่สามารถติดตามการปิดทรัพยากรทั้งหมดได้เสมอไป เพื่อให้ชีวิตของเราง่ายขึ้น นักพัฒนา 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 ("String can not be empty!");
    }
    return s;
}
ด้วยความสามารถของ Java ตั้งแต่เวอร์ชัน 7 เป็นต้นไป เราจึงสามารถรวมการจับข้อยกเว้นประเภทต่างๆ ไว้ในบล็อกเดียว ทำให้โค้ดมีขนาดกะทัดรัดและอ่านง่ายขึ้น ตัวอย่างเช่น:
public String input() {
    String s = null;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
        s = reader.readLine();
        if (s.equals("")) {
            throw new MyException("String can not be empty!");
        }
    } catch (IOException | MyException e) {
        System.out.println(e.getMessage());
    }
    return s;
}

ผลลัพธ์

การใช้ข้อยกเว้นใน Java ช่วยให้เราสามารถเพิ่มความทนทานต่อข้อบกพร่องของโปรแกรมผ่านการใช้เส้นทาง "สำรอง" เพื่อแยกตรรกะของโค้ดหลักออกจากโค้ดการจัดการข้อยกเว้นผ่านการใช้ catch block และยังช่วยให้เรา โอกาสในการมอบหมายการจัดการข้อยกเว้นให้กับผู้ใช้โค้ดของเราโดยใช้การพ่น
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION