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