1. บทนำ
ในการกวดวิชานี้เราจะครอบคลุมวิธีการสร้างข้อยกเว้นที่กำหนดเองใน Java
เราจะแสดงวิธีการนำข้อยกเว้นที่ผู้ใช้กำหนดมาใช้และใช้สำหรับข้อยกเว้นทั้งที่เลือกและไม่เลือก
2. ความต้องการข้อยกเว้นที่กำหนดเอง
ข้อยกเว้นของ Java ครอบคลุมข้อยกเว้นทั่วไปเกือบทั้งหมดที่เกิดขึ้นในการเขียนโปรแกรม
อย่างไรก็ตามบางครั้งเราจำเป็นต้องเสริมข้อยกเว้นมาตรฐานเหล่านี้ด้วยตัวของเราเอง
เหตุผลหลักในการแนะนำข้อยกเว้นที่กำหนดเอง ได้แก่ :
- ข้อยกเว้นตรรกะทางธุรกิจ - ข้อยกเว้นที่เฉพาะเจาะจงสำหรับตรรกะทางธุรกิจและเวิร์กโฟลว์ สิ่งเหล่านี้ช่วยให้ผู้ใช้แอปพลิเคชันหรือนักพัฒนาเข้าใจว่าปัญหาที่แท้จริงคืออะไร
- เพื่อตรวจจับและให้การปฏิบัติเฉพาะกับส่วนย่อยของข้อยกเว้น Java ที่มีอยู่
ข้อยกเว้น Java สามารถตรวจสอบและยกเลิกการเลือกได้ ในส่วนถัดไปเราจะกล่าวถึงทั้งสองกรณีนี้
3. ข้อยกเว้นการตรวจสอบที่กำหนดเอง
ข้อยกเว้นที่ตรวจสอบแล้วเป็นข้อยกเว้นที่ต้องได้รับการปฏิบัติอย่างชัดเจน
ลองพิจารณาโค้ดส่วนหนึ่งที่ส่งกลับบรรทัดแรกของไฟล์:
try (Scanner file = new Scanner(new File(fileName))) { if (file.hasNextLine()) return file.nextLine(); } catch(FileNotFoundException e) { // Logging, etc }
โค้ดด้านบนเป็นวิธีจัดการข้อยกเว้นที่ตรวจสอบ Java แบบคลาสสิก แม้ว่าโค้ดจะพ่นFileNotFoundException แต่ก็ไม่ชัดเจนว่าสาเหตุที่แท้จริงคืออะไร - ไม่ว่าไฟล์จะไม่มีอยู่หรือชื่อไฟล์ไม่ถูกต้อง
ในการสร้างข้อยกเว้นที่กำหนดเองเราต้องขยายคลาสjava.lang.Exception
ลองดูตัวอย่างนี้โดยการสร้างข้อยกเว้นที่ตรวจสอบเองที่เรียกว่าIncorrectFileNameException:
public class IncorrectFileNameException extends Exception { public IncorrectFileNameException(String errorMessage) { super(errorMessage); } }
โปรดทราบว่าเราต้องจัดเตรียมคอนสตรัคเตอร์ที่รับสตริงเป็นข้อความแสดงข้อผิดพลาดและเรียกตัวสร้างคลาสพาเรนต์
นี่คือทั้งหมดที่เราต้องทำเพื่อกำหนดข้อยกเว้นที่กำหนดเอง
ต่อไปมาดูกันว่าเราจะใช้ข้อยกเว้นที่กำหนดเองในตัวอย่างของเราได้อย่างไร:
try (Scanner file = new Scanner(new File(fileName))) { if (file.hasNextLine()) return file.nextLine(); } catch (FileNotFoundException e) { if (!isCorrectFileName(fileName)) { throw new IncorrectFileNameException("Incorrect filename : " + fileName ); } //... }
เราได้สร้างและใช้ข้อยกเว้นที่กำหนดเองดังนั้นผู้ใช้จึงสามารถทราบได้ว่าข้อยกเว้นที่แน่นอนคืออะไร แค่นี้ก็เพียงพอแล้ว? ดังนั้นเราจะสูญเสียสาเหตุของข้อยกเว้น
ในการแก้ไขปัญหานี้เรายังสามารถเพิ่มพารามิเตอร์java.lang.Throwableให้กับตัวสร้าง ด้วยวิธีนี้เราสามารถส่งผ่านข้อยกเว้นรูทไปยังการเรียกใช้เมธอด:
public IncorrectFileNameException(String errorMessage, Throwable err) { super(errorMessage, err); }
ตอนนี้IncorrectFileNameException ถูกใช้ร่วมกับสาเหตุหลักของข้อยกเว้นเช่นนี้:
try (Scanner file = new Scanner(new File(fileName))) { if (file.hasNextLine()) { return file.nextLine(); } } catch (FileNotFoundException err) { if (!isCorrectFileName(fileName)) { throw new IncorrectFileNameException( "Incorrect filename : " + fileName , err); } // ... }
นี่คือวิธีที่เราสามารถใช้ข้อยกเว้นที่กำหนดเองโดยไม่สูญเสียสาเหตุจากที่พวกเขาเกิดขึ้น
4. ข้อยกเว้นที่ไม่ได้ทำเครื่องหมายที่กำหนดเอง
ในตัวอย่างเดียวกันสมมติว่าเราต้องการข้อยกเว้นที่กำหนดเองหากชื่อไฟล์ไม่มีนามสกุลใด ๆ
ในกรณีนี้เราจำเป็นต้องมีข้อยกเว้นที่ไม่ได้ตรวจสอบที่กำหนดเองซึ่งคล้ายกับข้อผิดพลาดก่อนหน้านี้เนื่องจากจะตรวจพบข้อผิดพลาดนี้ในระหว่างรันไทม์เท่านั้น
ในการสร้างข้อยกเว้นที่ไม่ได้เลือกเองเราจำเป็นต้องขยายคลาสjava.lang.RuntimeException :
public class IncorrectFileExtensionException extends RuntimeException { public IncorrectFileExtensionException(String errorMessage, Throwable err) { super(errorMessage, err); } }
ดังนั้นเราสามารถใช้ข้อยกเว้นที่ไม่ได้ตรวจสอบที่กำหนดเองนี้ในตัวอย่างของเรา:
try (Scanner file = new Scanner(new File(fileName))) { if (file.hasNextLine()) { return file.nextLine(); } else { throw new IllegalArgumentException("Non readable file"); } } catch (FileNotFoundException err) { if (!isCorrectFileName(fileName)) { throw new IncorrectFileNameException( "Incorrect filename : " + fileName , err); } //... } catch(IllegalArgumentException err) { if(!containsExtension(fileName)) { throw new IncorrectFileExtensionException( "Filename does not contain extension : " + fileName, err); } //... }
5. สรุป
ข้อยกเว้นที่กำหนดเองมีประโยชน์มากเมื่อเราต้องจัดการข้อยกเว้นเฉพาะที่เกี่ยวข้องกับตรรกะทางธุรกิจ เมื่อใช้อย่างถูกต้องสามารถใช้เป็นเครื่องมือที่มีประโยชน์สำหรับการจัดการข้อยกเว้นและการบันทึกที่ดีขึ้น
โค้ดสำหรับตัวอย่างที่ใช้ในบทความนี้มีอยู่บน Github