ในฐานะที่เป็นมือใหม่ในการเขียนโปรแกรม แนวคิดของ การจัดการข้อยกเว้น อาจเป็นเรื่องยากที่จะคาดศีรษะ ไม่ใช่ว่าแนวคิดของตัวเองนั้นยาก แต่คำศัพท์สามารถทำให้ดูเหมือนล้ำหน้ากว่าที่เป็นอยู่ได้ และเป็นคุณลักษณะที่ทรงพลังที่มีแนวโน้มที่จะนำไปใช้ในทางที่ผิดและในทางที่ผิด
ในบทความนี้ คุณจะได้เรียนรู้ว่าข้อยกเว้นคืออะไร เหตุใดจึงสำคัญ วิธีใช้งาน และข้อผิดพลาดทั่วไปที่ควรหลีกเลี่ยง ภาษาสมัยใหม่ส่วนใหญ่มีการจัดการข้อยกเว้นบางประเภท ดังนั้นหากคุณเคยเปลี่ยนจาก Java คุณสามารถนำเคล็ดลับส่วนใหญ่เหล่านี้ติดตัวไปด้วยได้
ทำความเข้าใจข้อยกเว้น Java
ในชวา an ข้อยกเว้น เป็นวัตถุที่บ่งชี้สิ่งผิดปกติ (หรือ 'พิเศษ') เกิดขึ้นระหว่างการทำงานของแอปพลิเคชันของคุณ ข้อยกเว้นดังกล่าวคือ โยน ซึ่งโดยทั่วไปหมายถึงมีการสร้างวัตถุข้อยกเว้น (คล้ายกับข้อผิดพลาดที่ 'เพิ่ม')
ความสวยคือคุณทำได้ จับ ข้อยกเว้นซึ่งช่วยให้คุณจัดการกับเงื่อนไขที่ผิดปกติและอนุญาตให้แอปพลิเคชันของคุณทำงานต่อไปราวกับว่าไม่มีอะไรผิดพลาด ตัวอย่างเช่น ในขณะที่ตัวชี้ null ใน C อาจทำให้แอปพลิเคชันของคุณขัดข้อง Java ให้คุณโยนและจับ
NullPointerException
s ก่อนที่ตัวแปร null จะมีโอกาสทำให้เกิดความผิดพลาด
จำไว้ว่าข้อยกเว้นเป็นเพียงวัตถุ แต่มีลักษณะสำคัญอย่างหนึ่ง: ต้องขยายจาก
Exception
คลาสหรือคลาสย่อยใดๆ ของ
Exception
. แม้ว่า Java จะมีข้อยกเว้นในตัวทุกประเภท แต่คุณสามารถสร้างข้อยกเว้นของคุณเองได้หากต้องการ บางส่วนของ ข้อยกเว้น Java ที่พบบ่อยที่สุด รวม:
NullPointerException
NumberFormatException
IllegalArgumentException
RuntimeException
IllegalStateException
แล้วจะเกิดอะไรขึ้นเมื่อคุณโยนข้อยกเว้น?
ขั้นแรก Java จะดูภายในวิธีการทันทีเพื่อดูว่ามีโค้ดที่จัดการกับข้อยกเว้นประเภทที่คุณส่งหรือไม่ หากไม่มีตัวจัดการ มันจะดูที่วิธีที่เรียกวิธีการปัจจุบันเพื่อดูว่ามีหมายเลขอ้างอิงอยู่ที่นั่นหรือไม่ ถ้าไม่ดูวิธีที่เรียกว่า นั่น วิธีแล้ววิธีถัดไป ฯลฯ หากไม่พบข้อยกเว้น แอปพลิเคชันจะพิมพ์การติดตามสแต็กแล้วหยุดทำงาน (อันที่จริง มันมีความละเอียดอ่อนมากกว่าแค่การแครช แต่นั่นเป็นหัวข้อขั้นสูงที่อยู่นอกเหนือขอบเขตของบทความนี้)
ถึง การติดตามสแต็ก เป็นรายการของวิธีการทั้งหมดที่ Java สำรวจในขณะที่ค้นหาตัวจัดการข้อยกเว้น นี่คือลักษณะของการติดตามสแต็ก:
Exception in thread 'main' java.lang.NullPointerException
at com.example.myproject.Book.getTitle(Book.java:16)
at com.example.myproject.Author.getBookTitles(Author.java:25)
at com.example.myproject.Bootstrap.main(Bootstrap.java:14)
เราสามารถรวบรวมได้มากจากสิ่งนี้ ประการแรก ข้อยกเว้นที่ถูกโยนออกไปคือ a
NullPointerException
. มันเกิดขึ้นใน
getTitle()
วิธีการในบรรทัดที่ 16 ของ Book.java วิธีการนั้นถูกเรียกจาก
getBookTitles()
ในบรรทัดที่ 25 ของ Author.java ที่ วิธีการถูกเรียกจาก
main()
ในบรรทัดที่ 14 ของ Bootstrap.java อย่างที่คุณเห็น การรู้ทั้งหมดนี้ทำให้การดีบักง่ายขึ้น
แต่อีกครั้ง ประโยชน์ที่แท้จริงของข้อยกเว้นคือ คุณสามารถ 'จัดการ' เงื่อนไขที่ผิดปกติได้โดยจับข้อยกเว้น ตั้งค่าสิ่งต่าง ๆ ให้ถูกต้อง และเปิดแอปพลิเคชันต่อโดยไม่หยุดทำงาน
การใช้ข้อยกเว้น Java ใน Code
สมมติว่าคุณมี
someMethod()
ที่ใช้จำนวนเต็มและดำเนินการตรรกะบางอย่างที่อาจแตกได้หากจำนวนเต็มน้อยกว่า 0 หรือมากกว่า 100 นี่อาจเป็นที่ที่ดีในการโยนข้อยกเว้น:
แอพเดลิเวอรี่ตัวไหนจ่ายมากที่สุด
public void someMethod(int value) {
if (value 100) {
throw new IllegalArgumentException
เพื่อที่จะจับข้อยกเว้นนี้ คุณต้องไปที่
someMethod()
ถูกเรียกและใช้ บล็อกลองจับ :
public void callingMethod() {
try {
someMethod(200);
someOtherMethod();
} catch (IllegalArgumentException e) {
// handle the exception in here
}
// ...
}
ทุกอย่างภายใน ลอง บล็อกจะดำเนินการตามลำดับจนกว่าจะมีข้อยกเว้น ทันทีที่มีข้อยกเว้น ข้อความที่ตามมาทั้งหมดจะถูกข้ามและตรรกะของแอปพลิเคชันจะข้ามไปที่ . ทันที จับ บล็อก.
ในตัวอย่างของเรา เราเข้าสู่บล็อกการลองและโทรหา .ทันที
someMethod()
. เนื่องจาก 200 ไม่ใช่ระหว่าง 0 ถึง 100 ดังนั้น an
IllegalArgumentException
ถูกโยน การดำเนินการนี้จะสิ้นสุดการดำเนินการของ . ทันที
someMethod()
ข้ามส่วนที่เหลือของตรรกะในบล็อก try (
someOtherMethod()
ไม่เคยถูกเรียก) และดำเนินการดำเนินการต่อภายในบล็อก catch
จะเกิดอะไรขึ้นถ้าเราเรียก
someMethod(50)
แทนที่? NS
IllegalArgumentException
จะไม่มีวันถูกโยนทิ้ง
someMethod()
จะดำเนินการตามปกติ บล็อกลองจะทำงานตามปกติ เรียก
someOtherMethod()
เมื่อ someMethod() เสร็จสิ้น เมื่อไหร่
someOtherMethod()
สิ้นสุด บล็อก catch จะถูกข้ามและ
callingMethod()
จะดำเนินต่อไป
โปรดทราบว่าคุณสามารถมีบล็อก catch ได้หลายบล็อกต่อการลองบล็อก:
public void callingMethod() {
try {
someMethod(200);
someOtherMethod();
} catch (IllegalArgumentException e) {
// handle the exception in here
} catch (NullPointerException e) {
// handle the exception in here
}
// ...
}
โปรดทราบด้วยว่าตัวเลือกเสริม ในที่สุด บล็อกมีอยู่เช่นกัน:
public void method() {
try {
// ...
} catch (Exception e) {
// ...
} finally {
// ...
}
}
รหัสภายในบล็อกสุดท้ายคือ เสมอ ถูกประหารชีวิตไม่ว่าอะไรจะเกิดขึ้น หากคุณมีคำสั่ง return ในบล็อก try บล็อกสุดท้ายจะถูกดำเนินการก่อนที่จะออกจากเมธอด หากคุณส่งข้อยกเว้นอื่นในบล็อก catch บล็อกสุดท้ายจะถูกดำเนินการก่อนที่จะส่งข้อยกเว้น
คุณควรใช้บล็อกสุดท้ายเมื่อคุณมีวัตถุที่ต้องล้างก่อนที่วิธีการจะสิ้นสุด ตัวอย่างเช่น หากคุณเปิดไฟล์ในบล็อก try และต่อมาได้ส่งข้อยกเว้น บล็อกสุดท้ายจะให้คุณปิดไฟล์ก่อนที่จะออกจากเมธอด
โปรดทราบว่าคุณสามารถมีบล็อกสุดท้ายได้โดยไม่ต้องใช้บล็อก catch:
public void method() {
try {
// ...
} finally {
// ...
}
}
สิ่งนี้ช่วยให้คุณสามารถล้างข้อมูลที่จำเป็นในขณะที่อนุญาตให้ส่งข้อยกเว้นเพื่อเผยแพร่วิธีการเรียกใช้สแต็ก (เช่น คุณไม่ต้องการจัดการข้อยกเว้นที่นี่ แต่คุณยังจำเป็นต้องล้างข้อมูลก่อน)
ตรวจสอบกับข้อยกเว้นที่ไม่ได้ตรวจสอบใน Java
ต่างจากภาษาส่วนใหญ่ Java แยกความแตกต่างระหว่าง ตรวจสอบข้อยกเว้น และ ข้อยกเว้นที่ไม่ได้ตรวจสอบ (เช่น C# มีข้อยกเว้นที่ไม่ได้ตรวจสอบเท่านั้น) ข้อยกเว้นที่ตรวจสอบแล้ว ต้อง ติดอยู่กับวิธีการที่ส่งข้อยกเว้น มิฉะนั้นโค้ดจะไม่คอมไพล์
หากต้องการสร้างข้อยกเว้นที่ตรวจสอบ ให้ขยายจาก
Exception
. หากต้องการสร้างข้อยกเว้นที่ไม่ได้ตรวจสอบ ให้ขยายจาก
RuntimeException
.
เมธอดใดๆ ที่ส่งข้อยกเว้นที่ตรวจสอบแล้วต้องระบุสิ่งนี้ในลายเซ็นเมธอดโดยใช้ ขว้าง คำสำคัญ. เนื่องจาก Java ในตัว
IOException
เป็นข้อยกเว้นที่ตรวจสอบแล้ว โค้ดต่อไปนี้จะไม่คอมไพล์:
public void wontCompile() {
// ...
if (someCondition) {
throw new IOException();
}
// ...
}
คุณต้องประกาศก่อนว่ามีการตรวจสอบข้อยกเว้น:
public void willCompile() throws IOException {
// ...
if (someCondition) {
throw new IOException();
}
// ...
}
โปรดทราบว่าเมธอดสามารถประกาศเป็นการส่งข้อยกเว้นได้ แต่จะไม่ส่งข้อยกเว้นจริงๆ ถึงกระนั้นก็ยังต้องจับข้อยกเว้น มิฉะนั้นโค้ดจะไม่คอมไพล์
คุณควรใช้ข้อยกเว้นที่เลือกหรือไม่เลือกเมื่อใด
เอกสาร Java อย่างเป็นทางการมี a หน้าคำถามนี้ . สรุปความแตกต่างด้วยกฎง่ายๆ: 'ถ้าลูกค้าสามารถคาดหวังได้อย่างสมเหตุสมผลว่าสามารถกู้คืนจากข้อยกเว้นได้ ให้เป็นข้อยกเว้นที่ตรวจสอบแล้ว หากลูกค้าไม่สามารถดำเนินการใดๆ เพื่อกู้คืนจากข้อยกเว้นได้ ให้เป็นข้อยกเว้นที่ไม่ได้ตรวจสอบ'
แต่แนวทางนี้อาจล้าสมัย ในอีกด้านหนึ่ง การตรวจสอบข้อยกเว้นจะส่งผลให้โค้ดมีประสิทธิภาพมากขึ้น ในทางกลับกัน ไม่มีภาษาอื่นใดที่ตรวจสอบข้อยกเว้นในลักษณะเดียวกับ Java ซึ่งแสดงสองสิ่ง: หนึ่ง คุณลักษณะนี้ไม่มีประโยชน์เพียงพอสำหรับภาษาอื่น ๆ ที่จะขโมยมัน และสอง คุณสามารถอยู่ได้โดยปราศจากพวกเขา นอกจากนี้ ข้อยกเว้นที่ตรวจสอบแล้วยังเล่นได้ไม่ดีกับนิพจน์แลมบ์ดาที่นำมาใช้ใน Java 8
แนวทางการใช้ข้อยกเว้น Java
ข้อยกเว้นมีประโยชน์แต่นำไปใช้ในทางที่ผิดและถูกละเมิดได้ง่าย ต่อไปนี้คือเคล็ดลับและแนวทางปฏิบัติที่ดีที่สุดบางประการที่จะช่วยให้คุณไม่สร้างปัญหาให้ยุ่งยาก
- ต้องการข้อยกเว้นเฉพาะสำหรับข้อยกเว้นทั่วไป ใช้ |_+_| มากกว่า |_+_| เมื่อเป็นไปได้ มิฉะนั้นให้ใช้ |_+_| มากกว่า |_+_| เมื่อเป็นไปได้.
- ไม่เคยจับ |_+_| ! |_+_| คลาสจริงขยาย |_+_| และบล็อก catch ใช้งานได้จริงกับ |_+_| หรือคลาสใด ๆ ที่ขยาย Throwable อย่างไรก็ตาม |_+_| คลาสยังขยาย |_+_| และคุณไม่ต้องการที่จะจับ |_+_| เพราะ |_+_| บ่งบอกถึงปัญหาร้ายแรงที่ไม่สามารถกู้คืนได้
- ไม่เคยจับ |_+_| ! |_+_| ขยาย |_+_| ดังนั้นบล็อกใด ๆ ที่จับ |_+_| จะจับ |_+_| . ด้วย และนั่นเป็นข้อยกเว้นที่สำคัญมากที่คุณไม่ต้องการยุ่ง (โดยเฉพาะในแอปพลิเคชันแบบมัลติเธรด) เว้นแต่คุณจะรู้ว่าคุณกำลังทำอะไรอยู่ หากคุณไม่รู้ว่าจะจับข้อยกเว้นข้อใดแทน ให้พิจารณาว่าอย่าจับอะไรเลย
- ใช้ข้อความอธิบายเพื่อทำให้การดีบักง่ายขึ้น เมื่อคุณส่งข้อยกเว้น คุณสามารถระบุ |_+_| ข้อความเป็นอาร์กิวเมนต์ ข้อความนี้สามารถเข้าถึงได้ในบล็อก catch โดยใช้ |_+_| เมธอด แต่ถ้าไม่พบข้อยกเว้น ข้อความจะปรากฏเป็นส่วนหนึ่งของการติดตามสแต็ก
- พยายามอย่าจับและเพิกเฉยต่อข้อยกเว้น เพื่อหลีกเลี่ยงความไม่สะดวกของข้อยกเว้นที่ตรวจสอบ โปรแกรมเมอร์มือใหม่และขี้เกียจจำนวนมากจะตั้งค่าบล็อก catch แต่ปล่อยว่างไว้ แย่! จัดการกับมันอย่างสง่างามเสมอ แต่ถ้าทำไม่ได้ อย่างน้อยที่สุดก็พิมพ์สแต็กเทรซเพื่อให้คุณรู้ว่ามีข้อยกเว้นเกิดขึ้น คุณสามารถทำได้โดยใช้ |_+_| กระบวนการ.
- ระวังการใช้ข้อยกเว้นมากเกินไป เมื่อคุณมีค้อน ทุกอย่างก็ดูเหมือนตะปู เมื่อคุณเรียนรู้เกี่ยวกับข้อยกเว้นในครั้งแรก คุณอาจรู้สึกว่าจำเป็นต้องเปลี่ยนทุกอย่างให้เป็นข้อยกเว้น... จนถึงจุดที่โฟลว์การควบคุมส่วนใหญ่ของแอปพลิเคชันของคุณมีการจัดการข้อยกเว้น จำไว้ว่าข้อยกเว้นมีไว้สำหรับเหตุการณ์ที่ 'พิเศษ'!
ตอนนี้คุณควรจะสบายใจพอที่จะมีข้อยกเว้นเพื่อทำความเข้าใจว่ามันคืออะไร เหตุใดจึงใช้ และวิธีรวมเข้ากับโค้ดของคุณเอง หากคุณไม่เข้าใจแนวคิดทั้งหมดก็ไม่เป็นไร! ฉันต้องใช้เวลาสักพักกว่าจะ 'คลิก' ในหัว ดังนั้นอย่ารู้สึกว่าคุณต้องเร่งรีบ ใช้เวลาของคุณ
มีคำถามอะไรไหม? รู้เคล็ดลับอื่น ๆ ที่เกี่ยวข้องกับข้อยกเว้นที่ฉันพลาดไปหรือไม่? แบ่งปันในความคิดเห็นด้านล่าง!
แบ่งปัน แบ่งปัน ทวีต อีเมล วิธีสร้างไดอะแกรมการไหลของข้อมูลเพื่อแสดงข้อมูลของโครงการใด ๆ ไดอะแกรมกระแสข้อมูล (DFD) ของกระบวนการใดๆ ช่วยให้คุณเข้าใจว่าข้อมูลไหลจากต้นทางไปยังปลายทางอย่างไร นี่คือวิธีการสร้าง!
อ่านต่อไป หัวข้อที่เกี่ยวข้อง - การเขียนโปรแกรม
- Java
เกี่ยวกับผู้เขียน โจเอล ลี(ตีพิมพ์บทความ 1524) Joel Lee เป็นบรรณาธิการของ MakeUseOf ตั้งแต่ปี 2018 เขามีปริญญาตรี ในสาขาวิทยาการคอมพิวเตอร์และประสบการณ์การเขียนและแก้ไขอย่างมืออาชีพกว่าเก้าปี
amazon fire hd 8 google play
เพิ่มเติมจาก Joel Leeสมัครรับจดหมายข่าวของเรา
เข้าร่วมจดหมายข่าวของเราสำหรับเคล็ดลับทางเทคนิค บทวิจารณ์ eBook ฟรี และดีลพิเศษ!
คลิกที่นี่เพื่อสมัครสมาชิก