Adakah cara elegan untuk menangani pengecualian yang dilanggar finally
?
Sebagai contoh:
try {
// Use the resource.
}
catch( Exception ex ) {
// Problem with the resource.
}
finally {
try{
resource.close();
}
catch( Exception ex ) {
// Could not close the resource?
}
}
Bagaimana Anda menghindari try
/ catch
di finally
blok?
Resource
=>Closeable
?Saya biasanya menggunakan salah satu
closeQuietly
metode dalamorg.apache.commons.io.IOUtils
:sumber
Jika Anda menggunakan Java 7, dan
resource
implementasinyaAutoClosable
, Anda dapat melakukan ini (menggunakan InputStream sebagai contoh):sumber
Bisa dibilang agak berlebihan, tetapi mungkin berguna jika Anda membiarkan pengecualian muncul dan Anda tidak dapat mencatat apa pun dari dalam metode Anda (misalnya karena ini adalah perpustakaan dan Anda lebih suka membiarkan kode panggilan menangani pengecualian dan pencatatan):
PEMBARUAN: Saya melihat ini sedikit lebih banyak dan menemukan entri blog yang bagus dari seseorang yang secara jelas telah memikirkan hal ini lebih dari saya: http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make -mess-of-stream.html Dia melangkah lebih jauh dan menggabungkan dua pengecualian menjadi satu, yang menurut saya berguna dalam beberapa kasus.
sumber
ignore
pengecualianMulai dari Java 7, Anda tidak perlu lagi menutup sumber daya secara eksplisit di blok akhirnya, sebagai gantinya Anda dapat menggunakan sintaks try -with-resources. Pernyataan try-with-resources adalah pernyataan percobaan yang mendeklarasikan satu atau lebih resource. Sumber daya adalah objek yang harus ditutup setelah program selesai dengannya. Pernyataan coba-dengan-sumber daya memastikan bahwa setiap sumber daya ditutup di akhir pernyataan. Objek apa pun yang mengimplementasikan java.lang.AutoCloseable, yang menyertakan semua objek yang mengimplementasikan java.io.Closeable, bisa digunakan sebagai sumber daya.
Asumsikan kode berikut:
Jika terjadi pengecualian, metode penutupan akan dipanggil pada masing-masing dari ketiga sumber daya ini dalam urutan yang berlawanan saat dibuat. Ini berarti metode tutup akan dipanggil pertama untuk ResultSetm kemudian Pernyataan dan di akhir untuk objek Connection.
Penting juga untuk mengetahui bahwa pengecualian apa pun yang terjadi saat metode tutup dipanggil secara otomatis akan disembunyikan. Pengecualian yang disembunyikan ini bisa diambil dengan metode getsuppressed () yang ditentukan di kelas Throwable .
Sumber: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
sumber
Mengabaikan pengecualian yang terjadi dalam blok 'akhirnya' umumnya merupakan ide yang buruk kecuali seseorang mengetahui apa pengecualian itu dan kondisi apa yang akan mereka wakili. Dalam
try/finally
pola penggunaan normal ,try
blok menempatkan sesuatu ke dalam kondisi yang tidak diharapkan oleh kode luar, danfinally
blok mengembalikan status hal-hal itu ke apa yang diharapkan kode luar. Kode luar yang menangkap pengecualian umumnya akan mengharapkan bahwa, meskipun ada pengecualian, semuanya telah dikembalikan ke filenormal
negara. Misalnya, beberapa kode memulai transaksi dan kemudian mencoba menambahkan dua catatan; blok "akhirnya" melakukan operasi "rollback jika tidak dilakukan". Pemanggil mungkin bersiap untuk pengecualian terjadi selama eksekusi operasi "tambah" kedua, dan mungkin berharap bahwa jika ia menangkap pengecualian seperti itu, database akan berada dalam keadaan sebelum salah satu operasi dicoba. Namun, jika pengecualian kedua terjadi selama rollback, hal buruk dapat terjadi jika pemanggil membuat asumsi apa pun tentang status database. Kegagalan rollback merupakan krisis besar - krisis yang seharusnya tidak tertangkap oleh kode yang mengharapkan pengecualian hanya "Gagal menambahkan catatan".Kecenderungan pribadi saya akan memiliki metode akhirnya menangkap pengecualian yang terjadi dan membungkusnya dalam "CleanupFailedException", menyadari bahwa kegagalan tersebut merupakan masalah besar dan pengecualian tersebut tidak boleh dianggap enteng.
sumber
Salah satu solusinya, jika dua Pengecualian adalah dua kelas yang berbeda
Tetapi terkadang Anda tidak dapat menghindari coba-coba kedua ini. misalnya untuk menutup aliran
sumber
Mengapa Anda ingin menghindari blok tambahan? Karena blok terakhir berisi operasi "normal" yang dapat memunculkan pengecualian DAN Anda ingin blok akhirnya berjalan sepenuhnya, Anda HARUS menangkap pengecualian.
Jika Anda tidak mengharapkan blok akhirnya memunculkan pengecualian dan Anda tidak tahu bagaimana menangani pengecualian tersebut (Anda hanya akan membuang jejak tumpukan) biarkan pengecualian menggelembung ke tumpukan panggilan (hapus coba-tangkap dari blok).
Jika Anda ingin mengurangi pengetikan, Anda dapat menerapkan blok try-catch luar "global", yang akan menangkap semua pengecualian yang dilemparkan pada blok terakhir:
sumber
Setelah banyak pertimbangan, saya menemukan kode berikut yang terbaik:
Kode itu menjamin hal-hal berikut:
sumber
Jika Anda bisa, Anda harus menguji untuk menghindari kondisi kesalahan untuk memulai.
Juga Anda mungkin hanya menangkap pengecualian yang dapat Anda pulihkan, jika Anda tidak dapat memulihkan maka biarkan menyebar ke tingkat atas program Anda. Jika Anda tidak dapat menguji kondisi kesalahan bahwa Anda harus mengelilingi kode Anda dengan blok coba tangkap seperti yang sudah Anda lakukan (meskipun saya akan merekomendasikan untuk tetap menangkap kesalahan spesifik yang diharapkan).
sumber
Anda dapat mengubah ini menjadi metode lain ...
sumber
Saya biasanya melakukan ini:
Rasional: Jika saya sudah selesai dengan sumber daya dan satu-satunya masalah yang saya miliki adalah menutupnya, tidak banyak yang bisa saya lakukan. Tidak masuk akal juga untuk membunuh seluruh utas jika saya sudah selesai dengan sumber daya.
Ini adalah salah satu kasus ketika setidaknya bagi saya, aman untuk mengabaikan pengecualian yang dicentang itu.
Sampai hari ini saya tidak memiliki masalah menggunakan idiom ini.
sumber
Pekerjaan selesai. Tidak ada tes nol. Tangkapan tunggal, termasuk memperoleh dan melepaskan pengecualian. Tentu saja Anda dapat menggunakan idiom Execute Around dan hanya perlu menuliskannya sekali untuk setiap jenis resource.
sumber
Berubah
Resource
dari jawaban terbaik menjadiCloseable
Aliran mengimplementasikan
Closeable
Dengan demikian Anda dapat menggunakan kembali metode ini untuk semua aliransumber
Saya mengalami situasi serupa di mana saya tidak dapat menggunakan try dengan sumber daya tetapi saya juga ingin menangani pengecualian yang datang dari dekat, tidak hanya mencatat dan mengabaikannya seperti mekanisme closeQuietly. dalam kasus saya, saya tidak benar-benar berurusan dengan aliran keluaran, jadi kegagalan saat menutup lebih menarik daripada aliran sederhana.
sumber