จะเลือกข้อยกเว้นที่ทำเครื่องหมายและไม่เลือก


213

ใน Java (หรือภาษาอื่นที่มีข้อยกเว้นที่ตรวจสอบแล้ว) เมื่อสร้างคลาสยกเว้นของคุณเองคุณจะตัดสินใจได้อย่างไรว่าควรตรวจสอบหรือไม่เลือก

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


11
Barry Ruzek ได้เขียนคำแนะนำที่ยอดเยี่ยมเกี่ยวกับการเลือกข้อยกเว้นที่ทำเครื่องหมายหรือไม่ได้ตรวจสอบ
sigget

คำตอบ:


241

การตรวจสอบข้อยกเว้นนั้นยอดเยี่ยมตราบใดที่คุณเข้าใจว่าควรใช้เมื่อใด Java core API ล้มเหลวในการปฏิบัติตามกฎเหล่านี้สำหรับ SQLException (และบางครั้งสำหรับ IOException) ซึ่งเป็นสาเหตุที่ทำให้พวกเขาแย่มาก

ข้อยกเว้นการตรวจสอบควรจะใช้สำหรับคาดเดาได้แต่unpreventableข้อผิดพลาดที่เหมาะสมที่จะกู้คืนจาก

ควรใช้ข้อยกเว้นที่ไม่ได้ตรวจสอบกับทุกสิ่งอื่น

ฉันจะทำลายมันให้คุณเพราะคนส่วนใหญ่เข้าใจผิดว่านี่หมายถึงอะไร

  1. คาดการณ์ได้ แต่ไม่สามารถเตรียมตัวได้ : ผู้เรียกทำทุกอย่างที่อยู่ในอำนาจเพื่อตรวจสอบความถูกต้องของพารามิเตอร์อินพุต แต่เงื่อนไขบางอย่างที่อยู่นอกการควบคุมของพวกเขาได้ทำให้การดำเนินการล้มเหลว ตัวอย่างเช่นคุณลองอ่านไฟล์ แต่มีคนลบไฟล์ระหว่างเวลาที่คุณตรวจสอบว่ามีอยู่หรือไม่และเวลาที่การอ่านเริ่มต้นขึ้น โดยการประกาศข้อยกเว้นที่ตรวจสอบคุณจะบอกผู้โทรเพื่อคาดการณ์ความล้มเหลวนี้
  2. มีเหตุผลในการกู้คืนจาก : ไม่มีจุดบอกผู้โทรให้คาดการณ์ข้อยกเว้นที่ไม่สามารถกู้คืนได้ หากผู้ใช้พยายามอ่านจากไฟล์ที่ไม่มีอยู่ผู้เรียกสามารถแจ้งให้พวกเขาสำหรับชื่อไฟล์ใหม่ ในทางตรงกันข้ามหากวิธีการล้มเหลวเนื่องจากข้อผิดพลาดการเขียนโปรแกรม (ข้อโต้แย้งวิธีการที่ไม่ถูกต้องหรือการใช้วิธีการ buggy) ไม่มีอะไรที่แอปพลิเคชันสามารถทำได้เพื่อแก้ไขปัญหาในการดำเนินการกลาง วิธีที่ดีที่สุดที่สามารถทำได้คือบันทึกปัญหาและรอให้นักพัฒนาซอฟต์แวร์แก้ไขในภายหลัง

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

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

สำหรับทั้งข้อยกเว้นการตรวจสอบและไม่ จำกัดการใช้งานในระดับนามธรรมขวา ยกตัวอย่างเช่นที่เก็บรหัสกับสองการใช้งานที่แตกต่างกัน (ฐานข้อมูลและระบบแฟ้ม) ควรหลีกเลี่ยงการเปิดเผยรายละเอียดการดำเนินงานที่เฉพาะเจาะจงโดยการขว้างปาหรือSQLException IOExceptionแต่ควรห่อยกเว้นในสิ่งที่เป็นนามธรรมซึ่งครอบคลุมการใช้งานทั้งหมด (เช่นRepositoryException)


2
"คุณลองอ่านไฟล์ แต่มีบางคนลบมันในช่วงเวลาที่คุณตรวจสอบว่ามีอยู่หรือไม่และเวลาที่การอ่านเริ่มขึ้น" => สิ่งนี้จะ 'คาดหวัง' อย่างไร สำหรับฉันแล้วดูเหมือนว่า: ไม่คาดคิดและสามารถป้องกันได้ .. ใครจะคาดหวังว่าไฟล์จะถูกลบระหว่างคำสั่ง 2 รายการ?
Koray Tugay

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

ดังนั้นปัญหาใด ๆ ที่เกี่ยวข้องกับฐานข้อมูลภายในวิธีการจะต้องโยนข้อยกเว้นตรวจสอบ?
ivanjermakov

59

จากผู้เรียน Java :

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

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

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


13
นั่นคือมุมมองดั้งเดิม แต่มีข้อโต้แย้งมากมายเกี่ยวกับเรื่องนี้
artbristol

49

กฎที่ฉันใช้คือ: ห้ามใช้ข้อยกเว้นที่ไม่ได้ตรวจสอบ! (หรือเมื่อคุณไม่เห็นทางรอบ ๆ )

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


3
IMHO การตรวจสอบข้อยกเว้นอาจเป็นสินทรัพย์ที่สำคัญหากมีวิธีที่ง่ายสำหรับวิธีการประกาศว่ามันไม่ได้คาดหวังว่าวิธีการที่เรียกว่าในบล็อกของรหัสที่จะโยนข้อยกเว้นบางอย่าง (หรือที่ใดก็ได้) และการตรวจสอบใด ๆ ข้อยกเว้นที่ถูกโยนในทางตรงกันข้ามกับความคาดหวังดังกล่าวควรถูกห่อในประเภทข้อยกเว้นอื่น ๆ และส่งใหม่ ฉันวางตัวว่า 90% ของเวลาที่รหัสไม่ได้เตรียมที่จะรับมือกับข้อยกเว้นที่ตรวจสอบแล้วการห่อและทำใหม่จะเป็นวิธีที่ดีที่สุดในการจัดการ แต่เนื่องจากไม่มีภาษารองรับ
supercat

@supercat เป็นหลักนั่นคือ: ฉันเป็นแฟนตัวยงของการตรวจสอบประเภทที่เข้มงวดและการตรวจสอบข้อยกเว้นเป็นส่วนขยายตรรกะของที่ ฉันยกเลิกข้อยกเว้นที่ตรวจสอบอย่างสมบูรณ์แล้วแม้ว่าฉันจะชอบพวกเขามาก
Konrad Rudolph

1
One peeve ที่ฉันมีด้วยการออกแบบข้อยกเว้นซึ่งกลไกที่ฉันอธิบายไว้จะแก้ปัญหาคือถ้าfooมีการบันทึกเป็นการขว้างปาbarExceptionเมื่ออ่านผ่านจุดสิ้นสุดของไฟล์และfooเรียกวิธีการที่พ่นbarExceptionแม้ว่าfooจะไม่ได้คาดหวัง รหัสที่การโทรfooจะคิดว่าถึงจุดสิ้นสุดของไฟล์แล้วและจะไม่มีเงื่อนงำว่ามีบางสิ่งที่ไม่คาดคิดเกิดขึ้น ฉันคิดว่าสถานการณ์นั้นเป็นสถานการณ์ที่การยกเว้นที่ตรวจสอบควรมีประโยชน์มากที่สุด แต่ก็เป็นกรณีเดียวที่คอมไพเลอร์จะอนุญาตให้มีข้อยกเว้นที่ตรวจสอบไม่ได้จัดการ
supercat

@supercat: มีวิธีที่ง่ายสำหรับรหัสในการทำสิ่งที่คุณต้องการในความคิดเห็นแรก: ห่อรหัสในลองบล็อกจับข้อยกเว้นและตัดข้อยกเว้นใน RuntimeException และ rethrow
Warren Dew

1
@ KonradRudolph supercat ถูกอ้างถึง "บล็อกของรหัสพิเศษ"; เนื่องจากบล็อกต้องถูกกำหนดไวยากรณ์การประกาศจะไม่ลดความหมายของ bloat หากคุณคิดว่ามันจะเป็นการประกาศให้กับฟังก์ชั่นทั้งหมดนั่นก็จะเป็นการส่งเสริมการเขียนโปรแกรมที่ไม่ดีเพราะผู้คนจะติดอยู่ในการประกาศแทนที่จะมองที่ข้อยกเว้นที่ถูกตรวจสอบและอาจทำให้แน่ใจว่าไม่มีวิธีอื่นที่ดีกว่า เพื่อจัดการกับพวกเขา
Warren Dew

46

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

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

เวลาส่วนใหญ่คุณไม่ทราบว่าข้อผิดพลาดคือ "กู้คืนได้" เพราะคุณไม่ทราบว่าผู้เรียก API ของคุณอยู่ในชั้นใด

สมมติว่าฉันสร้าง StringToInt API ที่แปลงการแสดงสตริงของจำนวนเต็มเป็น Int ฉันต้องโยนข้อยกเว้นที่ตรวจสอบหรือไม่ถ้าเรียก API ด้วยสตริง "foo" มันสามารถกู้คืนได้? ฉันไม่รู้เพราะในเลเยอร์ของเขาผู้เรียกใช้ StringToInt API ของฉันอาจตรวจสอบอินพุตแล้วและถ้าข้อยกเว้นนี้เกิดขึ้นแสดงว่าเป็นข้อบกพร่องหรือข้อมูลเสียหายและไม่สามารถกู้คืนได้สำหรับเลเยอร์นี้

ในกรณีนี้ผู้เรียกใช้ API ไม่ต้องการตรวจจับข้อยกเว้น เขาเพียงต้องการที่จะให้ข้อยกเว้น "ฟองขึ้น" หากฉันเลือกข้อยกเว้นที่เลือกผู้โทรรายนี้จะมีบล็อก catch ที่ไร้ประโยชน์มากมายเพื่อสร้างข้อยกเว้นซ้ำ

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


3
นี้อยู่ใกล้กับuserstories.blogspot.com/2008/12/…
alexsmail

16
อินเทอร์เน็ต @alexsmail ไม่เคยล้มเหลวที่จะแปลกใจเลยที่จริงมันเป็นบล็อกของฉัน :)
สเตฟาน

30

คุณถูกต้อง

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

ตัวอย่างเช่น

/**
 * @params operation - The operation to execute.
 * @throws IllegalArgumentException if the operation is "exit"
 */
 public final void execute( String operation ) {
     if( "exit".equals(operation)){
          throw new IllegalArgumentException("I told you not to...");
     }
     this.operation = operation; 
     .....  
 }
 private void secretCode(){
      // we perform the operation.
      // at this point the opreation was validated already.
      // so we don't worry that operation is "exit"
      .....  
 }

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

 IllegalArgumentException: I told you not to use "exit" 
 at some.package.AClass.execute(Aclass.java:5)
 at otherPackage.Otherlass.delegateTheWork(OtherClass.java:4569)
 ar ......

และคุณจะรู้ว่าเกิดอะไรขึ้น OtherClass ในเมธอด "delegateTheWork" (ที่บรรทัด 4569) เรียกคลาสของคุณด้วยค่า "exit" แม้ว่าจะไม่ควรเป็นต้น

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

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

 public static MyClass createInstane( Object data1, Object data2 /* etc */ ){ 
      if( data1 == null ){ throw NullPointerException( "data1 cannot be null"); }

  }


  // the rest of the methods don't validate data1 anymore.
  public void method1(){ // don't worry, nothing is null 
      ....
  }
  public void method2(){ // don't worry, nothing is null 
      ....
  }
  public void method3(){ // don't worry, nothing is null 
      ....
  }

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

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

หากข้อยกเว้นที่ตรวจสอบมีการใช้มากเกินไป (โดยการเพิ่ม "ข้อยกเว้นการส่ง" ในลายเซ็นวิธีการทั้งหมด) รหัสของคุณจะบอบบางมากเพราะทุกคนจะเพิกเฉยต่อข้อยกเว้นนั้น (เพราะกว้างเกินไป) และคุณภาพของรหัสจะรุนแรง ที่ถูกบุกรุก

หากคุณใช้ข้อยกเว้นที่ไม่ได้ตรวจสอบมากเกินไปสิ่งที่คล้ายกันจะเกิดขึ้น ผู้ใช้รหัสนั้นไม่ทราบว่ามีบางอย่างผิดปกติลอง {... } catch (Throwable t) ได้มากจะปรากฏขึ้น


2
พูดได้ดี! +1 มันน่าประหลาดใจเสมอฉันนี้โทรความแตกต่าง (ไม่ได้ตรวจสอบ) / ถูกเรียก (ตรวจสอบ) ไม่ได้ชัดเจนมากขึ้น ...
VonC

19

นี่คือ 'กฎสุดท้ายของหัวแม่มือ' ของฉัน
ฉันใช้:

  • ข้อยกเว้นที่ไม่ได้ตรวจสอบภายในรหัสของวิธีการของฉันสำหรับความล้มเหลวเนื่องจากผู้โทร (ที่เกี่ยวข้องกับเอกสารที่ชัดเจนและสมบูรณ์ )
  • ตรวจสอบข้อยกเว้นสำหรับความล้มเหลวเนื่องจากผู้เรียกที่ฉันต้องการให้ชัดเจนกับทุกคนที่ต้องการใช้รหัสของฉัน

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


สำหรับข้อยกเว้นทั้งสองนี้ฉันจะสร้างข้อยกเว้นที่ไม่ได้ตรวจสอบและตรวจสอบของตัวเองสำหรับแอปพลิเคชันของฉัน (แนวปฏิบัติที่ดีตามที่กล่าวถึงที่นี่ ) ยกเว้นข้อยกเว้นที่ไม่ได้ตรวจสอบทั่วไป (เช่น NullPointerException)

ตัวอย่างเช่นเป้าหมายของฟังก์ชั่นเฉพาะด้านล่างนี้คือการสร้าง (หรือรับถ้ามีอยู่แล้ว) วัตถุซึ่งมี
ความหมาย:

  • ภาชนะของวัตถุที่จะทำให้ / ต้องมีอยู่ (ความรับผิดชอบของ CALLER
    => ข้อยกเว้นที่ไม่ได้ตรวจสอบ, และล้างความคิดเห็น javadoc สำหรับฟังก์ชั่นที่เรียกว่านี้)
  • พารามิเตอร์อื่นไม่สามารถเป็นโมฆะ
    (ตัวเลือกของ coder เพื่อวางไว้บน CALLER: coder จะไม่ตรวจสอบพารามิเตอร์ว่าง แต่ coder ทำเอกสาร)
  • ผลลัพธ์ไม่สามารถเป็นค่าว่างได้
    (ความรับผิดชอบและตัวเลือกของรหัสของผู้เลือกตัวเลือกที่น่าสนใจมากสำหรับผู้โทร
    => การตรวจสอบข้อยกเว้นเนื่องจากผู้โทรทุกคนต้องทำการตัดสินใจหากไม่สามารถสร้าง / พบวัตถุและ การตัดสินใจจะต้องบังคับใช้ในเวลารวบรวม: พวกเขาไม่สามารถใช้ฟังก์ชั่นนี้ได้โดยไม่ต้องจัดการกับความเป็นไปได้นี้หมายถึงการตรวจสอบนี้ข้อยกเว้นที่ )

ตัวอย่าง:


/**
 * Build a folder. <br />
 * Folder located under a Parent Folder (either RootFolder or an existing Folder)
 * @param aFolderName name of folder
 * @param aPVob project vob containing folder (MUST NOT BE NULL)
 * @param aParent parent folder containing folder 
 *        (MUST NOT BE NULL, MUST BE IN THE SAME PVOB than aPvob)
 * @param aComment comment for folder (MUST NOT BE NULL)
 * @return a new folder or an existing one
 * @throws CCException if any problems occurs during folder creation
 * @throws AssertionFailedException if aParent is not in the same PVob
 * @throws NullPointerException if aPVob or aParent or aComment is null
 */
static public Folder makeOrGetFolder(final String aFoldername, final Folder aParent,
    final IPVob aPVob, final Comment aComment) throws CCException {
    Folder aFolderRes = null;
    if (aPVob.equals(aParent.getPVob() == false) { 
       // UNCHECKED EXCEPTION because the caller failed to live up
       // to the documented entry criteria for this function
       Assert.isLegal(false, "parent Folder must be in the same PVob than " + aPVob); }

    final String ctcmd = "mkfolder " + aComment.getCommentOption() + 
        " -in " + getPNameFromRepoObject(aParent) + " " + aPVob.getFullName(aFolderName);

    final Status st = getCleartool().executeCmd(ctcmd);

    if (st.status || StringUtils.strictContains(st.message,"already exists.")) {
        aFolderRes = Folder.getFolder(aFolderName, aPVob);
    }
    else {
        // CHECKED EXCEPTION because the callee failed to respect his contract
        throw new CCException.Error("Unable to make/get folder '" + aFolderName + "'");
    }
    return aFolderRes;
}

19

มันไม่ใช่แค่ความสามารถในการกู้คืนจากข้อยกเว้น สิ่งที่สำคัญที่สุดในความคิดของฉันคือว่าผู้โทรมีความสนใจในการจับข้อยกเว้นหรือไม่

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

นี่คือปรัชญาที่ใช้โดยหลาย ๆ กรอบงาน ฤดูใบไม้ผลิและจำศีลโดยเฉพาะในใจ - พวกเขาแปลงข้อยกเว้นการตรวจสอบที่รู้จักกันเพื่อข้อยกเว้นที่ไม่ถูกตรวจสอบอย่างแม่นยำเพราะข้อยกเว้นการตรวจสอบจะใช้มากเกินไปใน Java ตัวอย่างหนึ่งที่ฉันนึกได้ก็คือ JSONException จาก json.org ซึ่งเป็นข้อยกเว้นที่ตรวจสอบแล้วและน่ารำคาญเป็นส่วนใหญ่ - ไม่ควรเลือก แต่ผู้พัฒนาก็ไม่ได้คิดถึงมัน

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


13

นี่คือทางออกที่ง่ายมากสำหรับภาวะที่กลืนไม่เข้าคายไม่ออกตรวจสอบ / ไม่ตรวจสอบของคุณ

กฎที่ 1: นึกถึงข้อยกเว้นที่ไม่ได้ตรวจสอบเป็นเงื่อนไขที่สามารถทดสอบได้ก่อนที่รหัสจะทำงาน ตัวอย่างเช่น…

x.doSomething(); // the code throws a NullPointerException

โดยที่ x เป็นโมฆะ ... ... โค้ดควรมีดังต่อไปนี้ ...

if (x==null)
{
    //do something below to make sure when x.doSomething() is executed, it won’t throw a NullPointerException.
    x = new X();
}
x.doSomething();

กฎที่ 2: คิดว่า Checked Exception เป็นเงื่อนไขที่ไม่สามารถทดสอบได้ซึ่งอาจเกิดขึ้นในขณะที่โค้ดทำงาน

Socket s = new Socket(“google.com”, 80);
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();

…ในตัวอย่างด้านบน URL (google.com) อาจไม่สามารถใช้งานได้เนื่องจากเซิร์ฟเวอร์ DNS หยุดทำงาน แม้ในทันทีที่เซิร์ฟเวอร์ DNS ใช้งานได้และแก้ไขชื่อ 'google.com' เป็นที่อยู่ IP หากการเชื่อมต่อนั้นถูกสร้างขึ้นที่ google.com ไม่ว่าในเวลาใดก็ตามเครือข่ายก็สามารถหยุดทำงานได้ คุณไม่สามารถทดสอบเครือข่ายได้ตลอดเวลาก่อนที่จะอ่านและเขียนไปยังสตรีม

มีบางครั้งที่รหัสจะต้องดำเนินการก่อนที่เราจะรู้ว่ามีปัญหา โดยการบังคับให้นักพัฒนาเขียนรหัสของพวกเขาในวิธีที่จะบังคับให้พวกเขาจัดการกับสถานการณ์เหล่านี้ผ่านการตรวจสอบข้อยกเว้นฉันต้องปลายหมวกของฉันกับผู้สร้างของ Java ที่คิดค้นแนวคิดนี้

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

มีพื้นที่สีเทาสำหรับสิ่งนี้ ในกรณีที่จำเป็นต้องมีการทดสอบจำนวนมาก (โปรดแจ้งให้ทราบหากมีคำสั่ง & & และ | |) ข้อยกเว้นที่เกิดขึ้นจะเป็น CheckedException เพียงเพราะมันเจ็บปวดมากเกินไปที่จะพูดให้ถูกต้อง - คุณไม่สามารถพูดปัญหานี้ได้ เป็นข้อผิดพลาดในการเขียนโปรแกรม หากมีการทดสอบน้อยกว่า 10 รายการ (เช่น 'if (x == null)') แสดงว่าข้อผิดพลาดของโปรแกรมเมอร์ควรเป็น UncheckedException

สิ่งที่น่าสนใจเมื่อต้องรับมือกับล่ามภาษา ตามกฎข้างต้นข้อผิดพลาดของไวยากรณ์ควรถูกพิจารณาว่าเป็นข้อยกเว้นที่ตรวจสอบหรือไม่ได้ตรวจสอบหรือไม่ ฉันจะยืนยันว่าถ้าไวยากรณ์ของภาษาสามารถทดสอบก่อนที่จะได้รับการดำเนินการก็ควร UncheckedException หากไม่สามารถทดสอบภาษาได้ - คล้ายกับวิธีที่แอสเซมบลีโค้ดทำงานบนคอมพิวเตอร์ส่วนบุคคลข้อผิดพลาดทางไวยากรณ์ควรเป็นข้อยกเว้นที่ตรวจสอบแล้ว

กฎ 2 ข้อข้างต้นอาจลบข้อกังวลของคุณ 90% ที่คุณต้องเลือก ในการสรุปกฎให้ทำตามรูปแบบนี้ ... 1) หากรหัสที่จะดำเนินการสามารถทดสอบได้ก่อนที่จะดำเนินการเพื่อให้ทำงานได้อย่างถูกต้องและหากมีข้อยกเว้นเกิดขึ้น - รู้จักข้อผิดพลาดของโปรแกรมเมอร์ข้อยกเว้นควรเป็น UncheckedException ) 2) หากรหัสที่จะดำเนินการไม่สามารถทดสอบได้ก่อนที่จะดำเนินการเพื่อให้ทำงานได้อย่างถูกต้องข้อยกเว้นควรเป็นข้อยกเว้นที่ตรวจสอบแล้ว (คลาสย่อยของข้อยกเว้น)


9

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


1
+1 สำหรับการกล่าวถึงว่าการทดสอบหน่วยอาจเป็นวิธีที่ดีกว่าในการแก้ปัญหาการตรวจสอบข้อยกเว้นมีวัตถุประสงค์เพื่อแก้ไข
Keith Pinson

+1 สำหรับการทดสอบหน่วย การใช้ข้อยกเว้น Checked / Uncheked มีผลกระทบเล็กน้อยต่อคุณภาพของรหัส ดังนั้นข้อโต้แย้งที่ว่าถ้ามีใครใช้ข้อยกเว้นที่ตรวจสอบแล้วมันจะส่งผลให้คุณภาพของรหัสที่ดีขึ้นคือการโต้แย้งที่สมบูรณ์!
user1697575

7

ข้อยกเว้นที่ตรวจสอบแล้ว: หากลูกค้าสามารถกู้คืนจากข้อยกเว้นและต้องการดำเนินการต่อให้ใช้ข้อยกเว้นที่ตรวจสอบ

ข้อยกเว้นที่ไม่ได้ตรวจสอบ: หากลูกค้าไม่สามารถทำสิ่งใด ๆ หลังจากข้อยกเว้นให้ยกข้อยกเว้นที่ไม่ได้ตรวจสอบ

ตัวอย่าง: หากคุณคาดว่าจะดำเนินการทางคณิตศาสตร์ในวิธี A () และขึ้นอยู่กับผลลัพธ์จาก A () คุณจะต้องดำเนินการอื่น หากเอาต์พุตเป็นโมฆะจากเมธอด A () ซึ่งคุณไม่ได้คาดหวังในระหว่างรันไทม์คุณจะต้องโยน Null pointer Exception ซึ่งเป็นข้อยกเว้นเวลารัน

อ้างอิงที่นี่


2

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

ฉันพบว่าข้อยกเว้นที่ตรวจสอบมีประโยชน์ในระดับต่ำกว่าเนื่องจากรายละเอียดการใช้งาน บ่อยครั้งดูเหมือนว่ากลไกการควบคุมที่ดีกว่าการจัดการข้อผิดพลาดที่ระบุ "รหัสส่งคืน" บางครั้งมันสามารถช่วยดูผลกระทบของแนวคิดสำหรับการเปลี่ยนรหัสระดับต่ำเช่นกัน ... ประกาศข้อยกเว้นที่ตรวจสอบดาวน์สตรีมและดูว่าใครจะต้องปรับเปลี่ยน จุดสุดท้ายนี้ใช้ไม่ได้หากมีจำนวนมากทั่วไป: catch (Exception e) หรือพ่น Exception ซึ่งโดยปกติแล้วจะไม่ได้คิดมากเกินไป


2

ที่นี่ฉันต้องการแบ่งปันความคิดเห็นของฉันฉันมีประสบการณ์การพัฒนาหลังจากหลายปี:

  1. ตรวจสอบข้อยกเว้น นี่เป็นส่วนหนึ่งของกรณีการใช้งานทางธุรกิจหรือการไหลของการโทรนี่เป็นส่วนหนึ่งของตรรกะการใช้งานที่เราคาดหวังหรือไม่ได้คาดหวัง ตัวอย่างเช่นการเชื่อมต่อถูกปฏิเสธเงื่อนไขไม่เป็นที่พอใจ ฯลฯ เราจำเป็นต้องจัดการและแสดงข้อความที่เกี่ยวข้องกับผู้ใช้พร้อมคำแนะนำว่าเกิดอะไรขึ้นและจะทำอย่างไรต่อไป (ลองอีกครั้งในภายหลังเป็นต้น) ฉันมักจะเรียกมันว่าข้อยกเว้นหลังการประมวลผลหรือข้อยกเว้น "ผู้ใช้"

  2. ข้อยกเว้นที่ไม่ได้ตรวจสอบ นี่เป็นส่วนหนึ่งของข้อยกเว้นการเขียนโปรแกรมข้อผิดพลาดบางประการในการเขียนโปรแกรมรหัสซอฟต์แวร์ (ข้อผิดพลาดข้อบกพร่อง) และสะท้อนให้เห็นถึงวิธีที่โปรแกรมเมอร์ต้องใช้ API ตามเอกสารประกอบ หากเอกสาร lib / framework ภายนอกกล่าวว่าคาดว่าจะได้รับข้อมูลในบางช่วงและไม่ใช่ค่าว่างเนื่องจาก NPE หรือ IllegalArgumentException จะถูกโยนทิ้งโปรแกรมเมอร์ควรคาดหวังและใช้ API อย่างถูกต้องตามเอกสารประกอบ มิฉะนั้นจะมีการโยนข้อยกเว้น ฉันมักจะเรียกมันว่าข้อยกเว้นการประมวลผลล่วงหน้าหรือข้อยกเว้น "การตรวจสอบ"

ตามกลุ่มเป้าหมาย ทีนี้มาพูดถึงกลุ่มเป้าหมายหรือกลุ่มคนที่ได้รับการออกแบบข้อยกเว้น (ตามความเห็นของฉัน):

  1. ตรวจสอบข้อยกเว้น กลุ่มเป้าหมายคือผู้ใช้ / ลูกค้า
  2. ข้อยกเว้นที่ไม่ได้ตรวจสอบ กลุ่มเป้าหมายคือนักพัฒนา อีกนัยหนึ่งคือข้อยกเว้นที่ไม่ได้ตรวจสอบถูกออกแบบมาสำหรับนักพัฒนาเท่านั้น

โดยระยะเวลาการพัฒนาแอพพลิเคชั่น

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

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


2

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

  • หากมีข้อผิดพลาดข้อผิดพลาดโปรแกรมเมอร์ก็ต้องมีข้อยกเว้นไม่ได้ตรวจสอบ ตัวอย่างเช่น: SQLException / IOException / NullPointerException ข้อยกเว้นเหล่านี้เป็นข้อผิดพลาดในการเขียนโปรแกรม พวกเขาควรได้รับการจัดการโดยโปรแกรมเมอร์ ขณะที่อยู่ใน JDBC API นั้น SQLException คือ Checked Exception ใน Spring JDBCT มันเป็น Unchecked Exception.Programmer ไม่ต้องกังวลกับ SqlException เมื่อใช้ Spring
  • หากข้อผิดพลาดไม่ใช่ข้อผิดพลาดของโปรแกรมเมอร์และสาเหตุมาจากภายนอกจะต้องเป็น Checked Exceptionตัวอย่างเช่น: หากไฟล์ถูกลบหรือมีการเปลี่ยนแปลงสิทธิ์ของไฟล์โดยบุคคลอื่นควรทำการกู้คืน

FileNotFoundException เป็นตัวอย่างที่ดีในการเข้าใจความแตกต่างที่ลึกซึ้ง FileNotFoundException ถูกส่งออกมาในกรณีที่ไม่พบไฟล์ มีสองเหตุผลสำหรับข้อยกเว้นนี้ หากเส้นทางไฟล์ถูกกำหนดโดยนักพัฒนาหรือการรับจากผู้ใช้ผ่าน GUI ก็ควรเป็นข้อยกเว้นที่ไม่ได้ตรวจสอบ หากบุคคลอื่นลบไฟล์นั้นควรเป็น Checked Exception

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

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


1

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

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


ฉันไม่เห็นด้วยกับข้อความของคุณว่า "ข้อยกเว้นที่ไม่ได้ตรวจสอบมีการใช้น้อยมากหากจริง ๆ " ในความเป็นจริงมันควรจะตรงกันข้าม! ใช้ exceprions ที่ไม่ถูกเลือกโดยค่าเริ่มต้นเมื่อคุณออกแบบลำดับชั้นข้อยกเว้นแอปพลิเคชันของคุณ ให้นักพัฒนาตัดสินใจเมื่อพวกเขาต้องการจัดการข้อยกเว้น (เช่นพวกเขาไม่ได้ถูกบังคับให้ใส่ catch block หรือวาง throw clause หากพวกเขาไม่รู้วิธีจัดการมัน)
user1697575

1

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

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

เมื่อใดก็ตามที่มีข้อยกเว้นการนำทางในเลเยอร์ที่แตกต่างกันเราไม่จำเป็นต้องจับมันในทุกเลเยอร์ในกรณีนั้นเราสามารถใช้ข้อยกเว้นรันไทม์หรือตัดข้อยกเว้นเป็นข้อยกเว้นที่ไม่ได้ตรวจสอบ

ข้อยกเว้นรันไทม์ถูกใช้เมื่อข้อยกเว้นส่วนใหญ่เกิดขึ้นไม่มีทางไปได้อีกและไม่มีสิ่งใดที่สามารถกู้คืนได้ ดังนั้นในกรณีนี้เราสามารถใช้ความระมัดระวังเกี่ยวกับข้อยกเว้นนั้น EX: NUllPointerException, ArrayOutofBoundsException สิ่งเหล่านี้มีแนวโน้มที่จะเกิดขึ้น ในสถานการณ์นี้เราสามารถใช้ความระมัดระวังขณะเข้ารหัสเพื่อหลีกเลี่ยงข้อยกเว้นดังกล่าว มิฉะนั้นเราจะต้องเขียนลองจับบล็อกทุกที่

สามารถทำการตรวจสอบข้อยกเว้นทั่วไปเพิ่มเติมได้, ตรวจสอบน้อยกว่าทั่วไป


1

ฉันคิดว่าเราสามารถคิดเกี่ยวกับข้อยกเว้นได้จากหลายคำถาม:

เหตุใดจึงมีการยกเว้น เราจะทำอย่างไรเมื่อมันเกิดขึ้น

โดยไม่ได้ตั้งใจข้อผิดพลาด เช่นวิธีการของวัตถุ null เรียกว่า

String name = null;
... // some logics
System.out.print(name.length()); // name is still null here

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

โดยการป้อนข้อมูลจากภายนอกคุณไม่สามารถควบคุมหรือเชื่อถือการส่งออกของบริการภายนอก

String name = ExternalService.getName(); // return null
System.out.print(name.length());    // name is null here

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

โดยข้อยกเว้นรันไทม์จากภายนอกคุณไม่สามารถควบคุมหรือเชื่อถือบริการภายนอก

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

โดยการตรวจสอบข้อยกเว้นจากภายนอกคุณไม่สามารถควบคุมหรือเชื่อถือบริการภายนอกได้

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

ในกรณีนี้เราจำเป็นต้องทราบว่ามีข้อยกเว้นประเภทใดเกิดขึ้นใน ExternalService หรือไม่ มันขึ้นอยู่กับ:

  1. หากคุณสามารถจัดการกับข้อยกเว้นบางประเภทคุณต้องจับพวกเขาและดำเนินการ สำหรับคนอื่น ๆ ให้ฟองสบู่

  2. หากคุณต้องการบันทึกหรือการตอบกลับถึงผู้ใช้ในการดำเนินการเฉพาะคุณสามารถตรวจสอบได้ สำหรับคนอื่น ๆ ให้ฟองสบู่


0

ฉันคิดว่าเมื่อประกาศ Application Exception ควรเป็น Unchecked Exception เช่น subclass ของ RuntimeException เหตุผลก็คือมันจะไม่ถ่วงรหัสแอปพลิเคชันด้วยการลองจับและส่งการประกาศบนวิธีการ หากแอปพลิเคชันของคุณใช้ Java Api ซึ่งจะมีการตรวจสอบข้อยกเว้นที่ต้องดำเนินการ สำหรับกรณีอื่น ๆ แอปพลิเคชันอาจมีข้อยกเว้นที่ไม่ได้ตรวจสอบ หากผู้เรียกใช้แอปพลิเคชันยังคงต้องการจัดการข้อยกเว้นที่ไม่ได้ตรวจสอบก็สามารถทำได้


-12

กฎที่ฉันใช้คือ: ห้ามใช้ข้อยกเว้นที่ไม่ได้ตรวจสอบ! (หรือเมื่อคุณไม่เห็นทางรอบ ๆ )

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

วิธีนี้ผู้ใช้ยังสามารถแสดงข้อความข้อผิดพลาดแทนแอปพลิเคชันหายไปโดยสมบูรณ์


1
คุณไม่ได้อธิบายสิ่งที่คุณคิดว่าผิดกับ catch-all สำหรับข้อยกเว้นที่ไม่ถูกตรวจสอบมากที่สุด
Matthew Flaschen

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