ความแตกต่างระหว่างลองในที่สุดและลองจับ


92

อะไรคือความแตกต่างระหว่าง

try {
    fooBar();
} finally {
    barFoo();
}

และ

try {
  fooBar();
} catch(Throwable throwable) {
    barFoo(throwable); // Does something with throwable, logs it, or handles it.
}

ฉันชอบเวอร์ชันที่สองมากกว่าเพราะมันทำให้ฉันสามารถเข้าถึง Throwable ได้ มีความแตกต่างทางตรรกะหรือรูปแบบที่ต้องการระหว่างสองรูปแบบหรือไม่?

นอกจากนี้ยังมีวิธีเข้าถึงข้อยกเว้นจากประโยคสุดท้ายหรือไม่?

คำตอบ:


123

นี่คือสองสิ่งที่แตกต่างกัน:

  • บล็อกการจับจะดำเนินการต่อเมื่อมีข้อยกเว้นเกิดขึ้นในบล็อกลอง
  • สุดท้ายบล็อกจะดำเนินการเสมอหลังจากบล็อก try (-catch) หากมีข้อยกเว้นเกิดขึ้นหรือไม่

ในตัวอย่างของคุณคุณไม่ได้แสดงโครงสร้างที่สามที่เป็นไปได้:

try {
    // try to execute this statements...
}
catch( SpecificException e ) {
    // if a specific exception was thrown, handle it here
}
// ... more catches for specific exceptions can come here
catch( Exception e ) {
    // if a more general exception was thrown, handle it here
}
finally {
    // here you can clean things up afterwards
}

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

แน่นอนคุณสามารถประกาศตัวแปรที่มีข้อยกเว้นนอกบล็อกของคุณและกำหนดค่าภายในบล็อก catch หลังจากนั้นคุณสามารถเข้าถึงตัวแปรนี้ภายในบล็อกสุดท้ายของคุณ

Throwable throwable = null;
try {
    // do some stuff
}
catch( Throwable e ) {
    throwable = e;
}
finally {
    if( throwable != null ) {
        // handle it
    }
}

11
ควันหลงว่าคือการที่คุณไม่สามารถเข้าถึงThrowableจากfinallyบล็อกเพราะมีอาจจะไม่เป็น Throwable
Dean Harding

11

สิ่งเหล่านี้ไม่ใช่รูปแบบ แต่เป็นสิ่งที่แตกต่างกันโดยพื้นฐาน finallyจะถูกดำเนินการเสมอ , catchเฉพาะเมื่อเกิดข้อยกเว้น


7

สุดท้ายและการจับบล็อกนั้นแตกต่างกันมาก:

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

ดังนั้น

try {
  //some code
}
catch (ExceptionA) {
  // Only gets executed if ExceptionA 
  // was thrown in try block
}
catch (ExceptionB) {
  // Only executed if ExceptionB was thrown in try 
  // and not handled by first catch block
}

แตกต่างจาก

try {
  //some code
}
finally {
  // Gets executed whether or not 
  // an exception was thrown in try block
}

อย่างมีนัยสำคัญ

หากคุณกำหนด try block คุณต้องกำหนด

  1. หนึ่งบล็อกในที่สุดหรือ
  2. บล็อกจับอย่างน้อยหนึ่งบล็อกหรือ
  3. บล็อกจับอย่างน้อยหนึ่งบล็อกและหนึ่งบล็อกในที่สุด

ดังนั้นรหัสต่อไปนี้ก็ใช้ได้เช่นกัน:

try {
  //some code
}
catch (ExceptionA) {
  // Only gets executed if 
  // ExceptionA was thrown in try block
}
catch (ExceptionB) {
  // Only executed if ExceptionB was thrown in 
  // try and not handled by first catch block
}
//even more catch blocks
finally {
  // Gets executed whether or not an 
  // exception was thrown in try block
}

4

try ใช้เพื่อเรียกใช้วิธีการที่อาจทำให้เกิดข้อยกเว้น

catch ใช้เพื่อ "จับ" หยุดข้อยกเว้นนั้น

finally ใช้สำหรับการทำความสะอาดใด ๆ ที่จำเป็นจากข้อยกเว้นที่ถูกจับหรือไม่

try{
    myObject.riskyMethod(); // run a method that may throw an exception
}
catch(Exception ex){
    myLogger.log(ex.Message); // "catch" stop that exception
}
finally{
    myObject = null; // clean up needed from that exception being caught
}

3
try {
    statements;
} catch (exceptionType1 e1) {      // one or multiple
    statements;                 
} catch (exceptionType2 e2) {
    statements;
}    
...
} finally {                                 // one or none
    statements;
}
  1. คำสั่ง try ทั้งหมดต้องมีคำสั่ง catch อย่างใดอย่างหนึ่งหรือประโยคสุดท้าย
  2. มันสามารถมีประโยค catch ได้หลายประโยค แต่สุดท้ายก็มีเพียงประโยคเดียว
  3. ในระหว่างการดำเนินการใด ๆ หากเกิดข้อผิดพลาดการควบคุมจะถูกโอนไปยังบล็อก Catch ที่เหมาะสมและเรียกใช้งานคำสั่งและในที่สุดบล็อกก็จะถูกดำเนินการ

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


3

สุดท้ายและการจับบล็อกนั้นแตกต่างกันมาก:

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


2

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


2

โดยทั่วไปเมื่อเราใช้ทรัพยากรใด ๆ เช่นสตรีมการเชื่อมต่อ ฯลฯ เราต้องปิดอย่างชัดเจนโดยใช้การบล็อกในที่สุด ในโปรแกรมที่ระบุด้านล่างเรากำลังอ่านข้อมูลจากไฟล์โดยใช้ FileReader และเรากำลังปิดโดยใช้บล็อกในที่สุด

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ReadData_Demo {

   public static void main(String args[]){
      FileReader fr=null;       
      try{
         File file=new File("file.txt");
         fr = new FileReader(file);  char [] a = new char[50];
         fr.read(a); // reads the content to the array
         for(char c : a)
         System.out.print(c); //prints the characters one by one
      }catch(IOException e){
          e.printStackTrace();
       }
       finally{ 
          try{
              fr.close();
          }catch(IOException ex){       
               ex.printStackTrace();
           }
       }
    }

}

บางทีคนอื่น ๆ เช่นฉันก็ค้นหาอะไรแบบนี้

ข้อมูลจากเพจนี้tutpoint


1

สุดท้ายบล็อกจะถูกดำเนินการเสมอ Catch block จะดำเนินการก็ต่อเมื่อมีการจับข้อยกเว้นที่ตรงกับพารามิเตอร์บล็อก


1

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


0

ลองบล็อกจะเก็บข้อความที่จะเพิ่มข้อยกเว้น บล็อกการจับจะเก็บข้อมูลอ้างอิงที่ส่งมาจากบล็อกการลองและข้อความที่ต้องการจะถูกสร้างขึ้นจากบล็อกการจับ สุดท้ายบล็อกยังใช้เพื่อปิดรีซอร์สที่ใช้เช่นการปิด io การปิดไฟล์การปิด dB ใน Java -9 รีซอร์สที่ได้รับการปรับปรุงขั้นสูงขึ้นมาโดยที่ทรัพยากรถูกประกาศนอกการลอง .. ในการเข้ารหัสลองด้วยทรัพยากรที่บล็อก catch เป็นข้อบังคับ

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