ฉันจะตรวจจับข้อยกเว้นทั้งหมดที่จะเกิดขึ้นจากการอ่านและเขียนไฟล์ได้อย่างไร


105

ใน Java มีวิธีใดบ้างในการรับ (catch) ทั้งหมดexceptionsแทนที่จะจับข้อยกเว้นทีละรายการ?


2
และฉันจะจับข้อยกเว้นเฉพาะเหล่านั้นทั้งหมดด้วย catch (Exception e) {} ??
Johanna

ใช่. เนื่องจาก Exception เป็นคลาสพื้นฐานของข้อยกเว้นทั้งหมดจึงมีข้อยกเว้น
jjnguy

1
@ jjnguy: ขอบคุณสำหรับคำอธิบายที่ดีของคุณ
Johanna

ฉันดีใจที่มีประโยชน์
jjnguy

คำตอบ:


111

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

รหัสมีลักษณะดังนี้:

public void someMethode() throws SomeCheckedException {

    //  code

}

จากนั้นคุณสามารถจัดการกับไฟล์ exceptionsกรณีที่คุณไม่ต้องการจัดการกับพวกเขาด้วยวิธีนั้น

ในการตรวจจับข้อยกเว้นทั้งหมดของโค้ดบางบล็อกอาจทำให้คุณทำได้: (สิ่งนี้จะจับExceptionsได้ว่าคุณเขียนเองด้วย)

try {

    // exceptional block of code ...

    // ...

} catch (Exception e){

    // Deal with e as you please.
    //e may be any type of exception at all.

}

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

หากคุณต้องการจัดการข้อยกเว้นของคุณเองก่อนอื่นให้เพิ่มcatchบล็อกก่อนข้อยกเว้นทั่วไป

try{    
}catch(MyOwnException me){
}catch(Exception e){
}

95

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

try{
    // IO code
} catch (Exception e){
    if(e instanceof IOException){
        // handle this exception type
    } else if (e instanceof AnotherExceptionType){
        //handle this one
    } else {
        // We didn't expect this one. What could it be? Let's log it, and let it bubble up the hierarchy.
        throw e;
    }
}

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

try{
    // IO code
} catch (Throwable t){
    if(t instanceof Exception){
        if(t instanceof IOException){
            // handle this exception type
        } else if (t instanceof AnotherExceptionType){
            //handle this one
        } else {
            // We didn't expect this Exception. What could it be? Let's log it, and let it bubble up the hierarchy.
        }
    } else if (t instanceof Error){
        if(t instanceof IOError){
            // handle this Error
        } else if (t instanceof AnotherError){
            //handle different Error
        } else {
            // We didn't expect this Error. What could it be? Let's log it, and let it bubble up the hierarchy.
        }
    } else {
        // This should never be reached, unless you have subclassed Throwable for your own purposes.
        throw t;
    }
}

12
ทำไมไม่ใช้บล็อกจับหลาย ๆ
Carl G

1
ฉันจะเถียงว่าคุณควรจับข้อยกเว้นแต่ละข้ออย่างชัดเจน แต่คำถามนั้นถามอย่างชัดเจนว่าจะจับทุกอย่างที่บล็อกของรหัสจะโยนได้อย่างไร
codethulhu

โยนได้นั้นมีประโยชน์
Anshul

นี่คือวิธีแก้ปัญหาที่ฉันกำลังมองหาฉันต้องการ if else สำหรับการจัดการข้อยกเว้น ขอบคุณ
CubeJockey

เคล็ดลับโยนได้มีประโยชน์จริงๆ
cherryhitech

15

จับข้อยกเว้นพื้นฐาน 'Exception'

   try { 
         //some code
   } catch (Exception e) {
        //catches exception and all subclasses 
   }

8
หากคุณเขียนโค้ดนี้คุณเกือบจะทำอะไรผิดพลาดอย่างมาก
จอร์จ

2
@ จอร์จทำไมถึงพูดแบบนั้น?
kuchi

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

2
โปรแกรมเขียนโค้ดส่วนใหญ่ที่ฉันเคยทำงานโดยไม่ใส่อะไรเลยในคำสั่ง catch ของพวกเขาดังนั้นการใช้ข้อมูลโค้ด try catch นี้ดีกว่าการจับข้อยกเว้นหลายประเภทและไม่ได้ทำอะไรเลย
Lou Morda

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

6

เป็นการปฏิบัติที่ไม่ดีในการจับข้อยกเว้น - มันกว้างเกินไปและคุณอาจพลาดบางอย่างเช่นNullPointerExceptionในโค้ดของคุณเอง

สำหรับการทำงานของไฟล์ส่วนใหญ่IOExceptionเป็นข้อยกเว้นของรูท ดีกว่าที่จะจับสิ่งนั้นแทน


1
เป็นการปฏิบัติที่ไม่ดีในการจับข้อยกเว้น ทำไม? downvote bad อธิบาย
Pedro Sequeira


4

คุณอาจพบข้อยกเว้นหลายข้อในบล็อกเดียว

try{
  // somecode throwing multiple exceptions;
} catch (Exception1 | Exception2 | Exception3 exception){
  // handle exception.
} 

3

คุณหมายถึงจับประเภทExceptionใดก็ได้ที่ถูกโยนซึ่งตรงข้ามกับข้อยกเว้นเฉพาะหรือไม่?

ถ้าเป็นเช่นนั้น:

try {
   //...file IO...
} catch(Exception e) {
   //...do stuff with e, such as check its type or log it...
}

จะทำยังไงให้คนที่ไม่เจาะจง ??
Johanna

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