Perbedaan antara coba-akhirnya dan coba-tangkap

91

Apa perbedaannya

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

dan

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

Saya lebih menyukai versi kedua karena memberikan saya akses ke Throwable. Apakah ada perbedaan logis atau kesepakatan yang disukai antara kedua variasi tersebut?

Juga, apakah ada cara untuk mengakses pengecualian dari klausa akhirnya?

Vijay Kotari
sumber

Jawaban:

121

Ini adalah dua hal yang berbeda:

  • Blok catch hanya dijalankan jika pengecualian dilemparkan ke blok percobaan.
  • Blok terakhir dijalankan selalu setelah blok try (-catch), jika pengecualian dilempar atau tidak.

Dalam contoh Anda, Anda belum menunjukkan kemungkinan konstruksi ketiga:

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
}

Dan, seperti yang dikatakan @codeca dalam komentarnya, tidak ada cara untuk mengakses pengecualian di dalam blok akhirnya, karena blok akhirnya dijalankan bahkan jika tidak ada pengecualian.

Tentu saja Anda bisa mendeklarasikan variabel yang menyimpan pengecualian di luar blok Anda dan menetapkan nilai di dalam blok catch. Setelah itu Anda dapat mengakses variabel ini di dalam blok terakhir Anda.

Throwable throwable = null;
try {
    // do some stuff
}
catch( Throwable e ) {
    throwable = e;
}
finally {
    if( throwable != null ) {
        // handle it
    }
}
tangens
sumber
11
Sebuah konsekuensi itu adalah bahwa Anda tidak dapat mengakses Throwabledari finallyblok, karena mungkin tidak menjadi sebuah Throwable.
Dean Harding
11

Ini bukanlah variasi, mereka pada dasarnya adalah hal yang berbeda. finallydijalankan selalu , catchhanya jika terjadi pengecualian.

Michiel Buddingh
sumber
7

Akhirnya dan blok tangkap sangat berbeda:

  • Di dalam blok tangkap Anda dapat menanggapi pengecualian yang dilempar. Blok ini dijalankan hanya jika ada pengecualian yang tidak tertangani dan jenisnya cocok dengan salah satu atau subkelas dari yang ditentukan dalam parameter blok catch.
  • Akhirnya akan selalu dieksekusi setelah blok coba dan tangkap apakah ada pengecualian yang dimunculkan atau tidak.

Begitu

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
}

berbeda dari

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

secara signifikan.

Jika Anda mendefinisikan blok percobaan, Anda harus mendefinisikan

  1. satu akhirnya memblokir, atau
  2. satu atau lebih blok tangkapan, atau
  3. satu atau lebih blok tangkap dan satu blok terakhir

Jadi kode berikut akan valid juga:

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
}
TheMorph
sumber
4

try digunakan untuk menjalankan metode yang mungkin memunculkan pengecualian

catch digunakan untuk "menangkap" menghentikan pengecualian itu

finally digunakan untuk pembersihan apa pun yang diperlukan dari pengecualian yang tertangkap atau tidak

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
}
Kieran
sumber
3
try {
    statements;
} catch (exceptionType1 e1) {      // one or multiple
    statements;                 
} catch (exceptionType2 e2) {
    statements;
}    
...
} finally {                                 // one or none
    statements;
}
  1. Semua pernyataan percobaan harus menyertakan salah satu klausa tangkapan atau klausa akhirnya
  2. Ini dapat memiliki beberapa klausa tangkapan tetapi hanya satu klausa akhirnya
  3. Selama eksekusi apapun, jika terjadi kesalahan, maka Kontrol akan ditransfer ke blok Catch yang sesuai dan mengeksekusi pernyataan dan blok Akhirnya dieksekusi.

Tidak peduli apa Blok Akhirnya selalu dijalankan, Jadi secara umum, blok Akhirnya digunakan, ketika Anda memiliki sesi, koneksi Database atau File atau soket terbuka, maka kode untuk menutup koneksi tersebut akan ditempatkan. Ini hanya untuk memastikan dalam aplikasi tidak ada kebocoran memori atau masalah lain tidak boleh terjadi.

gmhk
sumber
3

Akhirnya dan blok tangkap sangat berbeda:

Di dalam blok tangkap Anda dapat menanggapi pengecualian yang dilempar. Blok ini dijalankan hanya jika ada pengecualian yang tidak tertangani dan jenisnya cocok dengan salah satu atau subkelas dari yang ditentukan dalam parameter blok catch. Akhirnya akan selalu dieksekusi setelah blok coba dan tangkap apakah ada pengecualian yang dimunculkan atau tidak.

Tutorial Android
sumber
2

Dalam penelitian saya Akhirnya blokir selalu dijalankan dan ini terutama "digunakan untuk menutup semua koneksi yang terbuka" dan untuk menghancurkan sesuatu yang berjalan tidak perlu.

Hari krishna
sumber
2

Umumnya ketika kita menggunakan sumber daya seperti aliran, koneksi dll .. kita harus menutupnya secara eksplisit menggunakan blok terakhir. Dalam program yang diberikan di bawah ini kami membaca data dari file menggunakan FileReader dan kami menutupnya menggunakan blok terakhir.

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();
           }
       }
    }

}

Mungkin orang lain seperti saya mencari sesuatu seperti ini.

Informasi dari tutpoint halaman ini


sumber
1

Akhirnya blok selalu dijalankan. Catch block dijalankan hanya jika pengecualian yang cocok dengan parameter blok ditangkap.

mkorpela.dll
sumber
1

Bahkan dalam bentuk pertama Anda bisa memasukkannya ke dalam metode panggilan. Jadi tidak ada keuntungan besar kecuali Anda ingin melakukan penanganan khusus di sana.

fastcodejava.dll
sumber
0

Coba blok akan menahan pernyataan yang akan menimbulkan pengecualian. Blok catch akan menahan referensi yang dilempar dari blok try dan pesan yang diperlukan dihasilkan dari blok catch. Akhirnya blok juga digunakan untuk menutup sumber daya yang digunakan seperti penutupan io, penutupan file, penutupan dB .. Di Java -9 peningkatan coba-dengan sumber daya muncul di mana sumber daya dideklarasikan di luar percobaan .. dalam percobaan yang ditingkatkan dengan sumber daya blok tangkapan adalah wajib

srinija
sumber