JavaRush /จาวาบล็อก /Random-TH /ข้อยกเว้น: เลือกแล้ว ไม่เลือก และของคุณเอง

ข้อยกเว้น: เลือกแล้ว ไม่เลือก และของคุณเอง

เผยแพร่ในกลุ่ม
สวัสดี! ในการบรรยายครั้งล่าสุด เราได้ทำความคุ้นเคยกับแง่มุมหนึ่งของภาษา Java เป็นข้อยกเว้น และได้เห็นตัวอย่างการทำงานกับสิ่งเหล่านี้ วันนี้เราจะมาดูโครงสร้างของมันให้ละเอียดยิ่งขึ้น และเรียนรู้วิธีเขียนข้อยกเว้นของเราเอง :)

ประเภทของข้อยกเว้น

อย่างที่เราบอกไป มีคลาสข้อยกเว้นมากมายใน Java เกือบ 400 คลาส! แต่พวกมันทั้งหมดถูกแบ่งออกเป็นกลุ่ม ดังนั้นจึงค่อนข้างง่ายที่จะจดจำพวกมัน มีลักษณะดังนี้: ข้อยกเว้น: เลือกแล้ว ไม่เลือกและของคุณเอง - 2ข้อยกเว้นทั้งหมดมีคลาสบรรพบุรุษร่วมThrowableกัน กลุ่มใหญ่สองกลุ่มมาจากมัน - ข้อยกเว้น (ข้อยกเว้น) และข้อผิดพลาด (ข้อผิดพลาด) ข้อผิดพลาดคือข้อผิดพลาดร้ายแรงระหว่างการทำงานของโปรแกรมที่เกี่ยวข้องกับการทำงานของเครื่องเสมือน Java ในกรณีส่วนใหญ่ ข้อผิดพลาดไม่จำเป็นต้องได้รับการจัดการ เพราะมันบ่งบอกถึงข้อบกพร่องร้ายแรงบางประการในโค้ด ข้อผิดพลาดที่มีชื่อเสียงที่สุด: StackOverflowError- เกิดขึ้นเมื่อวิธีการเรียกตัวเองอย่างไม่มีที่สิ้นสุด และOutOfMemoryError- เกิดขึ้นเมื่อมีหน่วยความจำไม่เพียงพอที่จะสร้างวัตถุใหม่ อย่างที่คุณเห็นในสถานการณ์เหล่านี้ ส่วนใหญ่มักจะไม่มีอะไรพิเศษในการประมวลผล - โค้ดนั้นเขียนไม่ถูกต้องและจำเป็นต้องทำใหม่ ข้อยกเว้นในความเป็นจริงแล้ว ข้อยกเว้น: สถานการณ์พิเศษที่ไม่ได้วางแผนไว้ซึ่งเกิดขึ้นในขณะที่โปรแกรมกำลังทำงาน ข้อผิดพลาดเหล่านี้ไม่ใช่ข้อผิดพลาดที่ร้ายแรงเท่ากับข้อผิดพลาด แต่ต้องได้รับการดูแลจากเรา ข้อยกเว้นทั้งหมดแบ่งออกเป็น 2 ประเภท - กาเครื่องหมาย ( กาเครื่องหมาย ) และไม่ถูกกาเครื่องหมาย ( unchecked ) ข้อยกเว้น: เลือกแล้ว ไม่เลือก และของคุณเอง - 3ข้อยกเว้นที่เลือกทั้งหมดมาจากException. “ตรวจสอบได้” หมายความว่าอย่างไร เราได้กล่าวถึงสิ่งนี้บางส่วนในการบรรยายครั้งล่าสุด : “...คอมไพเลอร์ Java รู้เกี่ยวกับข้อยกเว้นที่พบบ่อยที่สุด และรู้ว่าข้อยกเว้นเหล่านั้นสามารถเกิดขึ้นได้ในสถานการณ์ใด” ตัวอย่างเช่น เขารู้ว่าถ้าโปรแกรมเมอร์อ่านข้อมูลจากไฟล์ในโค้ด สถานการณ์อาจเกิดขึ้นได้ง่ายว่าไม่มีไฟล์อยู่ และมีสถานการณ์เช่นนี้มากมายที่เขาสามารถคาดเดาล่วงหน้าได้ ดังนั้นคอมไพลเลอร์จะตรวจสอบโค้ดของเราล่วงหน้าเพื่อดูข้อยกเว้นที่อาจเกิดขึ้น หากพบมันจะไม่รวบรวมโค้ดจนกว่าเราจะประมวลผลหรือส่งต่อไปยังด้านบน ข้อยกเว้นประเภทที่สองคือ "ไม่ได้เลือก" พวกเขามาจากชั้นRuntimeExceptionเรียน แตกต่างจากที่ทดสอบอย่างไร? ดูเหมือนว่าจะมีคลาสต่างๆ มากมายที่มาจากRuntimeExceptionและอธิบายข้อยกเว้นรันไทม์เฉพาะ ข้อแตกต่างคือคอมไพเลอร์ไม่คาดหวังข้อผิดพลาดเหล่านี้ ดูเหมือนว่าเขาจะพูดว่า: “ในขณะที่เขียนโค้ด ฉันไม่พบสิ่งใดที่น่าสงสัย แต่มีบางอย่างผิดพลาดในขณะที่มันกำลังทำงานอยู่ เห็นได้ชัดว่ามีข้อผิดพลาดในโค้ด!” และก็เป็นเช่นนั้นจริงๆ ข้อยกเว้นที่ไม่ได้ตรวจสอบมักเป็นผลมาจากข้อผิดพลาดของโปรแกรมเมอร์ และคอมไพเลอร์ไม่สามารถจัดเตรียมสถานการณ์ที่ไม่ถูกต้องที่เป็นไปได้ทั้งหมดที่ผู้คนสามารถสร้างด้วยมือของตนเองได้อย่างชัดเจน :) ดังนั้นมันจะไม่ตรวจสอบการจัดการข้อยกเว้นดังกล่าวในโค้ดของเรา คุณพบข้อยกเว้นที่ไม่ได้ตรวจสอบหลายประการแล้ว:
  • ArithmeticExceptionเกิดขึ้นเมื่อหารด้วยศูนย์
  • ArrayIndexOutOfBoundsExceptionเกิดขึ้นเมื่อพยายามเข้าถึงเซลล์ภายนอกอาร์เรย์
ตามทฤษฎีแล้ว แน่นอนว่าผู้สร้าง Java อาจแนะนำการจัดการข้อยกเว้นดังกล่าวแบบบังคับ แต่โค้ดจะเป็นอย่างไร? ในการหารตัวเลขใดๆ คุณจะต้องเขียน try-catch เพื่อตรวจสอบว่าคุณกำลังหารด้วยศูนย์โดยไม่ตั้งใจหรือไม่? เมื่อใดก็ตามที่เข้าถึงอาร์เรย์ คุณจะต้องเขียน try-catch เพื่อตรวจสอบว่าคุณได้เกินขีดจำกัดเหล่านี้หรือไม่ โค้ดใดๆ ที่เขียนขึ้นจะเป็นสปาเก็ตตี้และไม่สามารถอ่านได้ทั้งหมด เป็นเหตุผลที่ความคิดนี้ถูกยกเลิก ดังนั้น ข้อยกเว้นที่ไม่ได้ตรวจสอบไม่จำเป็นต้องได้รับการจัดการในบล็อก try-catch หรือโยนไปที่ด้านบน แม้ว่าจะเป็นไปได้ในทางเทคนิค เช่นเดียวกับข้อผิดพลาดก็ตาม

วิธีการโยนข้อยกเว้นของคุณ

แน่นอนว่าผู้สร้าง Java ไม่สามารถจัดเตรียมสถานการณ์พิเศษทั้งหมดที่อาจเกิดขึ้นในโปรแกรมได้ มีโปรแกรมมากมายในโลกนี้ และมันต่างกันเกินไป แต่ก็ไม่เป็นไร เพราะคุณสามารถสร้างข้อยกเว้นของคุณเองได้หากจำเป็น ทำได้ง่ายมาก สิ่งที่คุณต้องทำคือสร้างชั้นเรียนของคุณเอง ชื่อต้องลงท้ายด้วย "ข้อยกเว้น" คอมไพเลอร์ไม่ต้องการสิ่งนี้ แต่โปรแกรมเมอร์ที่อ่านโค้ดของคุณจะเข้าใจทันทีว่านี่คือคลาสข้อยกเว้น Exceptionนอกจากนี้ คุณต้องระบุว่าคลาส นั้นมาจากคลาส นี่เป็นสิ่งจำเป็นสำหรับคอมไพเลอร์และการดำเนินการที่ถูกต้องแล้ว เช่น เรามีคลาส Dog - Dog. เราสามารถพาสุนัขไปเดินเล่นได้โดยwalk()ใช้ แต่ก่อนอื่นเราต้องตรวจสอบว่าสัตว์เลี้ยงของเราสวมปลอกคอ สายจูง และปากกระบอกปืนหรือไม่ หากไม่มีสิ่งใดเหล่านี้ เราจะโยนข้อยกเว้นของเราDogIsNotReadyExceptionเอง รหัสของมันจะมีลักษณะดังนี้:
public class DogIsNotReadyException extends Exception {

   public DogIsNotReadyException(String message) {
       super(message);
   }
}
เพื่อระบุว่าคลาสนั้นเป็นข้อยกเว้น คุณต้องเขียนส่วนขยาย Exceptionหลังชื่อคลาส: ซึ่งหมายความว่า "คลาสนั้นมาจากคลาส Exception" ในตัวสร้างเราจะเรียกตัวสร้างคลาสExceptionด้วยบรรทัดmessage- มันจะแสดงข้อความจากระบบให้ผู้ใช้ทราบถึงข้อผิดพลาดที่เกิดขึ้น นี่คือสิ่งที่จะมีลักษณะเช่นนี้ในรหัสชั้นเรียนของเรา:
public class Dog {

   String name;
   boolean isCollarPutOn;
   boolean isLeashPutOn;
   boolean isMuzzlePutOn;

   public Dog(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

   }

   public void putCollar() {

       System.out.println("The collar is on!");
       this.isCollarPutOn = true;
   }

   public void putLeash() {

       System.out.println("The leash is on!");
       this.isLeashPutOn = true;
   }

   public void putMuzzle() {
       System.out.println("The muzzle is on!");
       this.isMuzzlePutOn = true;
   }

   public void walk() throws DogIsNotReadyException {

   System.out.println("Let's go for a walk!");
   if (isCollarPutOn && isLeashPutOn && isMuzzlePutOn) {
       System.out.println("Hurrah, let's go for a walk!" + name + " I am glad!");
   } else {
       throw new DogIsNotReadyException("Dog " + name + "not ready for a walk! Check your gear!");
   }
 }

}
ตอนนี้วิธีการของเราwalk()ส่งข้อDogIsNotReadyExceptionยกเว้น ทำได้โดยใช้คำthrowหลัก ดังที่เราได้กล่าวไว้ก่อนหน้านี้ ข้อยกเว้นคือวัตถุ ดังนั้นตามวิธีการของเรา เมื่อเกิดสถานการณ์พิเศษ - มีบางอย่างหายไปในสุนัข - เราจะสร้างคลาสอ็อบเจ็กต์ใหม่DogIsNotReadyExceptionและโยนมันลงในโปรแกรมโดยใช้คำว่าthrow. walk()เราเพิ่มการโยนให้กับวิธีการ ลายDogIsNotReadyExceptionเซ็น กล่าวอีกนัยหนึ่ง คอมไพเลอร์ทราบแล้วว่าการเรียกใช้เมธอดwalk()อาจส่งผลให้เกิดข้อยกเว้น ดังนั้นเมื่อเราเรียกสิ่งนี้ที่ไหนสักแห่งในโปรแกรม ข้อยกเว้นจะต้องได้รับการจัดการ ลองทำสิ่งนี้ในวิธีการmain():
public static void main(String[] args) {

   Dog dog = new Dog("Mukhtar");
   dog.putCollar();
   dog.putMuzzle();
   dog.walk();//Unhandled exception: DogIsNotReadyException
}
ไม่คอมไพล์ ข้อยกเว้นไม่ได้รับการจัดการ! มาล้อมโค้ดของเราไว้ในบล็อกtry-catchเพื่อจัดการกับข้อยกเว้น:
public static void main(String[] args) {

   Dog dog = new Dog("Mukhtar");
   dog.putCollar();
   dog.putMuzzle();
   try {
       dog.walk();
   } catch (DogIsNotReadyException e) {
       System.out.println(e.getMessage());
       System.out.println("Checking equipment! Is the collar on?" + dog.isCollarPutOn + "\r\n Is the leash on?"
       + dog.isLeashPutOn + "\r\n Are you wearing a muzzle?" + dog.isMuzzlePutOn);
   }
}
ตอนนี้เรามาดูผลลัพธ์ของคอนโซล:

Ошейник надет! 
Намордник надет! 
Собираемся на прогулку! 
Собака Мухтар не готова к прогулке! Проверьте экипировку! 
Проверяем снаряжение! Ошейник надет? true
Поводок надет? false 
Намордник надет? true
ดูสิว่าเอาต์พุตคอนโซลมีข้อมูลมากขึ้นแค่ไหน! เราเห็นทุกขั้นตอนที่เกิดขึ้นในโปรแกรม เราจะเห็นว่าข้อผิดพลาดเกิดขึ้นที่ใดและสังเกตได้ทันทีว่าสุนัขของเราขาดอะไรไป :) นี่คือวิธีที่เราสร้างข้อยกเว้นของเราเอง อย่างที่คุณเห็นไม่มีอะไรซับซ้อน และถึงแม้ว่านักพัฒนา Java ไม่ได้ใส่ใจที่จะเพิ่มข้อยกเว้นพิเศษสำหรับภาษาของพวกเขาสำหรับสุนัขที่ติดตั้งไม่ถูกต้อง แต่เราได้แก้ไขการกำกับดูแลของพวกเขา :)
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION