ความแตกต่างระหว่างข้อยกเว้นและข้อผิดพลาด


173

ฉันพยายามเรียนรู้เพิ่มเติมเกี่ยวกับ Java พื้นฐานและประเภท Throwables ที่แตกต่างกันใครสามารถแจ้งให้ฉันทราบถึงความแตกต่างระหว่างข้อยกเว้นและข้อผิดพลาดได้หรือไม่?

คำตอบ:


178

ไม่ควรจับหรือจัดการข้อผิดพลาด (ยกเว้นในกรณีที่หาได้ยาก) ข้อยกเว้นคือขนมปังและเนยของการจัดการข้อยกเว้น Javadocอธิบายได้ดี:

ข้อผิดพลาดเป็นคลาสย่อยของ Throwable ที่ระบุปัญหาร้ายแรงที่แอปพลิเคชันที่สมเหตุสมผลไม่ควรลองจับ ข้อผิดพลาดดังกล่าวส่วนใหญ่เป็นเงื่อนไขที่ผิดปกติ

ดูคลาสย่อยErrorบางส่วนของรับความคิดเห็น JavaDoc ของพวกเขา:

  • AnnotationFormatError - ถูกโยนทิ้งเมื่อตัวแยกวิเคราะห์คำอธิบายประกอบพยายามอ่านคำอธิบายประกอบจากไฟล์คลาสและพิจารณาว่าคำอธิบายประกอบนั้นมีรูปแบบไม่ถูกต้อง
  • AssertionError - โยนเพื่อระบุว่าการยืนยันล้มเหลว
  • LinkageError- คลาสย่อยของ LinkageError ระบุว่าคลาสมีการพึ่งพาบางอย่างในคลาสอื่น แม้กระนั้นชั้นหลังมีการเปลี่ยนแปลงอย่างไม่ลงรอยกันหลังจากการรวบรวมของชั้นเดิม
  • VirtualMachineError - โยนเพื่อระบุว่า Java Virtual Machine ใช้งานไม่ได้หรือทรัพยากรหมดซึ่งจำเป็นต่อการใช้งานต่อไป

มีหมวดหมู่ย่อยที่สำคัญสามประการของThrowable:

  • Error - มีบางอย่างที่รุนแรงพอผิดพลาดแอปพลิเคชั่นส่วนใหญ่ควรหยุดทำงานแทนที่จะพยายามจัดการกับปัญหา
  • ข้อยกเว้นที่ไม่ได้ตรวจสอบ (aka RuntimeException) - บ่อยครั้งมากที่ข้อผิดพลาดในการเขียนโปรแกรมเช่นNullPointerExceptionหรืออาร์กิวเมนต์ที่ผิดกฎหมาย บางครั้งแอปพลิเคชันสามารถจัดการหรือกู้คืนจากThrowableหมวดหมู่นี้- หรืออย่างน้อยก็จับได้ที่run()วิธีการของเธรดบันทึกการร้องเรียนและทำงานต่อไป
  • Checked Exception (aka ทุกอย่างอื่น) - แอปพลิเคชันคาดว่าจะสามารถจับและทำสิ่งที่มีความหมายกับส่วนที่เหลือเช่นFileNotFoundExceptionและTimeoutException...

10
ออราเคิลกล่าวว่าUnchecked exceptions != RuntimeExceptions; Unchecked exceptions = RuntimeExceptions + Errors. ฉันรู้ว่ามันทำให้เกิดคำถาม: ข้อผิดพลาดเป็นข้อยกเว้น? แต่นี่คือสิ่งที่พวกเขาเขียน นี่เป็นเพียงแค่หนึ่งในตัวอย่างเหล่านั้นdocs.oracle.com/javase/tutorial/essential/exceptions/...
ROMANIA_engineer

1
คำถามที่ไม่มีคำตอบคือ RuntimeException และ Error แตกต่างกันอย่างไรในสาระสำคัญ? ทั้งสองจะถูกตรวจสอบและเท่าเทียมกันในทุก ๆ ทาง
Pacerier

38

สไลด์นี้แสดงลำดับชั้นข้อยกเว้นของ Javaโดย@ georgios-gousiosโดยสังเขปอธิบายถึงความแตกต่างระหว่างข้อผิดพลาดและข้อยกเว้นใน Java

ลำดับชั้นของข้อยกเว้น Java


6
ฉันชอบที่จะเห็นใครบางคนที่กำลังฟื้นตัวจาก NullPointerException: D: D: D
Ignacio Soler Garcia

2
@IgnacioSolerGarcia มันอาจเป็นไปได้และมันก็มีเหตุผล (คำถามอื่น ๆ ก็คือถ้ามันดี) โดยปกติคุณตรวจสอบว่ามีวัตถุอยู่หรือไม่และหลังจากนั้นเรียกใช้เมธอดหรือใช้ฟิลด์ แต่คุณสามารถตรวจสอบการมีอยู่ลองจับ NPE แทน และบันทึกข้อความเกี่ยวกับมันและไปเช่น
นักเลง

@Gangnus: ไม่มีเหตุผล โปรดจำไว้ว่าข้อยกเว้นจะข้ามบางส่วนของรหัสและเป็นวิธีการรายงานข้อผิดพลาดไม่ใช่การทำงานปกติ
Ignacio Soler Garcia

17

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

ตัวอย่าง: OutOfMemoryError - ไม่มากที่คุณสามารถทำได้เนื่องจากโปรแกรมของคุณไม่สามารถรันได้อีกต่อไป

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

ตัวอย่าง: IllegalArgumentException - ส่งผ่านข้อมูลที่ไม่ถูกต้องไปยังเมธอดเพื่อให้การเรียกเมธอดล้มเหลว แต่ไม่มีผลต่อการดำเนินการในอนาคต

ตัวอย่างเหล่านี้เป็นแบบง่าย ๆ และมีข้อมูลอีกมากมายเกี่ยวกับข้อยกเว้นเพียงอย่างเดียว


ดูexample.javacodegeeks.com/java-basics/exceptions/…เป็นตัวอย่าง IllegalArgumentException เป็นข้อยกเว้นรันไทม์ไม่ใช่ข้อผิดพลาด docs.oracle.com/javase/7/docs/api/java/lang/…
Gangnus

8

ข้อผิดพลาด -

  1. Errors ใน java java.lang.Errorเป็นประเภท
  2. ข้อผิดพลาดทั้งหมดใน java เป็นประเภทที่ไม่ได้ตรวจสอบ
  3. Errorเกิดขึ้นในเวลาทำงาน พวกเขาจะไม่รู้จักคอมไพเลอร์
  4. ไม่สามารถกู้คืนจากข้อผิดพลาดได้
  5. Errors ส่วนใหญ่เกิดจากสภาพแวดล้อมที่แอปพลิเคชันทำงานอยู่
  6. ตัวอย่าง: java.lang.StackOverflowError ,java.lang.OutOfMemoryError

ข้อยกเว้น -

  1. Exceptions ใน java java.lang.Exceptionเป็นประเภท
  2. Exceptions รวมทั้งประเภทที่เลือกและไม่ถูกตรวจสอบ
  3. ข้อยกเว้นที่ตรวจสอบแล้วเป็นที่ทราบกันว่าคอมไพเลอร์โดยที่ไม่ทราบข้อยกเว้นที่ไม่ได้ตรวจสอบเนื่องจากคอมไพเลอร์เกิดขึ้นในขณะดำเนินการ
  4. คุณสามารถกู้คืนจากข้อยกเว้นโดยจัดการผ่านtry-catchบล็อก
  5. Exceptions ส่วนใหญ่เกิดจากแอปพลิเคชันนั้นเอง
  6. ตัวอย่าง:ข้อยกเว้นการยืม: SQLException, IOException
    ข้อยกเว้นไม่ได้ตรวจสอบ: ArrayIndexOutOfBoundException, ClassCastException,NullPointerException

อ่านเพิ่มเติม: http://javaconceptoftheday.com/difference-between-error-vs-exception-in-java/ http://javaconceptoftheday.com/wp-content/uploads/2015/04/ErrorVsException.png



3

คำอธิบายของErrorชั้นเรียนค่อนข้างชัดเจน:

An Errorเป็นคลาสย่อยThrowable ที่ระบุถึงปัญหาร้ายแรงที่แอพพลิเคชั่นที่เหมาะสมไม่ควรลองจับ ข้อผิดพลาดดังกล่าวส่วนใหญ่เป็นเงื่อนไขที่ผิดปกติ ThreadDeath ข้อผิดพลาดแม้ว่าสภาพ "ปกติ" ยังเป็น subclass ของErrorเพราะใช้งานมากที่สุดไม่ควรพยายามที่จะจับมัน

วิธีการไม่จำเป็นต้องประกาศในการส่งคำสั่งย่อยคลาสย่อยใด ๆ ของ Errorที่อาจถูกโยนในระหว่างการดำเนินการของวิธีการ แต่ไม่จับเนื่องจากข้อผิดพลาดเหล่านี้เป็นเงื่อนไขที่ผิดปกติที่ไม่ควรเกิดขึ้น

อ้างจากตัวเองของ Java เอกสารของชั้นเรียนError

ในระยะสั้นคุณไม่ควรจับErrors ยกเว้นว่าคุณมีเหตุผลที่ดีที่จะทำเช่นนั้น (ตัวอย่างเช่นเพื่อป้องกันการนำเว็บเซิร์ฟเวอร์ของคุณไปใช้งานล้มเหลวหากเซิร์ฟเล็ตมีหน่วยความจำไม่เพียงพอหรือเป็นเช่นนั้น)

Exceptionบนมืออื่น ๆ ที่เป็นเพียงข้อยกเว้นตามปกติในภาษาที่ทันสมัยอื่น ๆ คุณจะพบคำอธิบายโดยละเอียดในเอกสารประกอบ Java API หรือแหล่งข้อมูลออนไลน์หรือออฟไลน์


2

มีหลายความเหมือนและความแตกต่างระหว่างชั้นเรียนและjava.lang.Exceptionjava.lang.Error

ความคล้ายคลึงกัน:

  • ครั้งแรก - ชั้นเรียนทั้งขยายjava.lang.Throwableและเป็นผลให้สืบทอดหลายวิธีการซึ่งเป็นเรื่องธรรมดาที่จะถูกนำมาใช้เมื่อต้องรับมือกับข้อผิดพลาดเช่น: getMessage, getStackTrace, printStackTraceและอื่น ๆ

  • ประการที่สองเป็น subclasses ของjava.lang.Throwableพวกเขาทั้งสองสืบทอดคุณสมบัติต่อไปนี้:

    • Throwable ตัวเองและใด ๆ ของ subclasses (รวมถึงjava.lang.Error) สามารถประกาศในรายการข้อยกเว้นวิธีการใช้throwsคำหลัก การประกาศดังกล่าวจำเป็นสำหรับjava.lang.Exceptionและ subclasses สำหรับjava.lang.Throwable, java.lang.Errorและjava.lang.RuntimeExceptionและ subclasses ของพวกเขามันเป็นตัวเลือก

    • เฉพาะjava.lang.Throwableคลาสย่อยที่ได้รับอนุญาตให้ใช้ในcatchอนุประโยค

    • เท่านั้นjava.lang.Throwableและ subclasses สามารถนำมาใช้กับคำ throw-

ข้อสรุปจากที่พักแห่งนี้อยู่ต่อไปทั้งในjava.lang.Errorและjava.lang.Exceptionสามารถประกาศในส่วนหัวของวิธีการที่สามารถอยู่ในประโยคที่สามารถใช้กับคำหลักcatchthrow

แตกต่าง:

  • ความแตกต่างแรกแนวคิด: java.lang.Errorออกแบบมาเพื่อโยนโดย JVM และระบุปัญหาร้ายแรงและตั้งใจที่จะหยุดการทำงานของโปรแกรมแทนที่จะถูกจับ (แต่เป็นไปได้สำหรับjava.lang.Throwableผู้สืบทอดอื่น ๆ)

    ข้อความจากคำอธิบายjavadocเกี่ยวกับjava.lang.Error:

    ... บ่งชี้ถึงปัญหาร้ายแรงที่แอปพลิเคชั่นที่สมเหตุสมผลไม่ควรพยายามจับ

    ตรงกันข้ามjava.lang.Exceptionออกแบบมาเพื่อแสดงถึงข้อผิดพลาดที่คาดหวังและสามารถจัดการได้โดยโปรแกรมเมอร์โดยไม่ต้องยุติการทำงานของโปรแกรม

    ข้อความจากคำอธิบายjavadocเกี่ยวกับjava.lang.Exception:

    ... ระบุเงื่อนไขที่แอปพลิเคชันที่สมเหตุสมผลอาจต้องการจับ

  • ข้อแตกต่างที่สองระหว่างjava.lang.Errorและjava.lang.Exceptionครั้งแรกนั้นถือว่าเป็นข้อยกเว้นที่ไม่ได้ตรวจสอบสำหรับการตรวจสอบข้อยกเว้นเวลาคอมไพล์ เนื่องจากการโยนรหัสผลลัพธ์java.lang.Errorหรือคลาสย่อยไม่จำเป็นต้องประกาศข้อผิดพลาดนี้ในส่วนหัวของเมธอด ขณะขว้างปาjava.lang.Exceptionการประกาศที่จำเป็นในส่วนหัวของวิธีการ

Throwable และแผนภาพคลาสตัวต่อ (คุณสมบัติและเมธอดถูกละเว้น) ป้อนคำอธิบายรูปภาพที่นี่


1

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

ตัวอย่าง:

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


1

ข้อผิดพลาดส่วนใหญ่เกิดจากสภาพแวดล้อมที่แอปพลิเคชันทำงานอยู่ ตัวอย่างเช่น OutOfMemoryError เกิดขึ้นเมื่อ JVM มีหน่วยความจำไม่เพียงพอหรือ StackOverflowError เกิดขึ้นเมื่อสแตกโอเวอร์โฟลว์

ข้อยกเว้นส่วนใหญ่เกิดจากแอปพลิเคชันเอง ตัวอย่างเช่น NullPointerException เกิดขึ้นเมื่อแอปพลิเคชันพยายามเข้าถึงวัตถุ Null หรือ ClassCastException เกิดขึ้นเมื่อแอปพลิเคชันพยายามที่จะส่งประเภทคลาสที่เข้ากันไม่ได้

แหล่งที่มา: ความแตกต่างระหว่างข้อผิดพลาด Vs ข้อยกเว้นใน Java


"ข้อผิดพลาดส่วนใหญ่เกิดจากสภาพแวดล้อมที่แอปพลิเคชันทำงานอยู่" และ "ข้อยกเว้นส่วนใหญ่เกิดจากแอปพลิเคชันเอง" สมบูรณ์แบบ!
ADJ

0

นี่เป็นบทสรุปที่ดีจาก Java API ความหมายของข้อผิดพลาดและข้อยกเว้น:

ข้อผิดพลาดเป็นคลาสย่อยของ Throwable ที่ระบุปัญหาร้ายแรงที่แอปพลิเคชันที่สมเหตุสมผลไม่ควรลองจับ ข้อผิดพลาดดังกล่าวส่วนใหญ่เป็นเงื่อนไขที่ผิดปกติ ข้อผิดพลาด ThreadDeath แม้ว่าจะเป็นเงื่อนไข "ปกติ" ก็เป็นคลาสย่อยของข้อผิดพลาดเนื่องจากแอปพลิเคชันส่วนใหญ่ไม่ควรลองจับมัน

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

OTOH สำหรับข้อยกเว้น Java API พูดว่า:

ข้อยกเว้นคลาสและคลาสย่อยเป็นรูปแบบของ Throwable ที่ระบุเงื่อนไขที่แอปพลิเคชันที่สมเหตุสมผลอาจต้องการจับ


0

ข้อผิดพลาดเกิดจากสภาพแวดล้อมที่แอปพลิเคชันหรือโปรแกรมของคุณทำงาน เวลาส่วนใหญ่คุณอาจไม่สามารถกู้คืนได้เนื่องจากจะทำให้แอปพลิเคชันหรือโปรแกรมของคุณสิ้นสุด Javadoc แนะนำว่าคุณไม่ควรรำคาญข้อผิดพลาดดังกล่าวเนื่องจากสภาพแวดล้อมเช่น JVM ข้อผิดพลาดดังกล่าวกำลังจะออกไป

ตัวอย่าง: VirtualMachineError- โยนเพื่อระบุว่า Java Virtual Machine ใช้งานไม่ได้หรือทรัพยากรหมดที่จำเป็นสำหรับการใช้งานต่อไป OutOfMemoryErrorเกิดขึ้นเมื่อ JVM มีหน่วยความจำStackOverflowErrorไม่เพียงพอหรือ เกิดขึ้นเมื่อ stack หมด

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

ตัวอย่าง: NullPointerExceptionเกิดขึ้นเมื่อแอปพลิเคชันพยายามเข้าถึงวัตถุ null หรือพยายามเข้าถึงอาร์เรย์ด้วยดัชนีที่ไม่มีอยู่หรือเรียกใช้ฟังก์ชันที่มีข้อมูลหรือพารามิเตอร์ที่ไม่ถูกต้อง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.