วิธีจัดการกับข้อยกเว้น Java อย่างถูกวิธี

วิธีจัดการกับข้อยกเว้น Java อย่างถูกวิธี

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





ในบทความนี้ คุณจะได้เรียนรู้ว่าข้อยกเว้นคืออะไร เหตุใดจึงสำคัญ วิธีใช้งาน และข้อผิดพลาดทั่วไปที่ควรหลีกเลี่ยง ภาษาสมัยใหม่ส่วนใหญ่มีการจัดการข้อยกเว้นบางประเภท ดังนั้นหากคุณเคยเปลี่ยนจาก 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 ฟรี และดีลพิเศษ!

คลิกที่นี่เพื่อสมัครสมาชิก