Perbedaan antara menggunakan Throwable dan Exception dalam try catch

Jawaban:

247

Dengan menangkap Throwableitu termasuk hal-hal yang subclass Error. Anda umumnya tidak boleh melakukan itu, kecuali mungkin pada tingkatan "tangkap semua" yang paling tinggi di mana Anda ingin masuk atau menangani sepenuhnya semua yang dapat salah. Ini akan lebih khas dalam aplikasi jenis kerangka kerja (misalnya server aplikasi atau kerangka kerja pengujian) di mana ia dapat menjalankan kode yang tidak dikenal dan tidak boleh dipengaruhi oleh apa pun yang salah dengan kode itu, sebanyak mungkin.

Yishai
sumber
30
Mungkin akan lebih baik untuk menjelaskan sedikit hirarki di sini.
Xonatron
11
Konteks untuk jawaban ini: Throwable menyertakan Error dan Exception sebagai subclass, jadi try / catch pertama termasuk yang kedua tetapi biasanya terlalu luas.
Noel
2
Ini juga mencakup subclass langsung yang ditentukan pengguna Throwable dan instance Throwable sendiri. Tidak ada yang menghentikan Anda dari menulis throw new Throwable();, jadi itu adalah satu-satunya cara untuk benar-benar menangkap semuanya.
Antimony
3
Meskipun diterima, ini tidak menjawab pertanyaan karena sebagian besar jawaban menggambarkan praktik terbaik untuk menangkap Pengecualian dan Throwable, dan pertanyaannya adalah tentang perbedaan (seperti kapan harus menggunakannya dan kapan saya mau). "Ini termasuk hal-hal yang termasuk dalam Kesalahan subkelas" adalah satu-satunya perbedaan yang ditentukan dan itu benar-benar jawaban yang komprehensif: Apa itu Kesalahan? Mengapa penting bahwa itu termasuk itu? Adakah perbedaan atau praktik terbaik lainnya?
Oded Niv
@OdedNiv "Apa itu Kesalahan? Mengapa penting bahwa itu termasuk kesalahan itu?" Anda dapat bertanya pada mereka dalam pertanyaan lain.
Kronen
182

Yang pertama menangkap semua subclass dari Throwable (ini termasuk Exceptiondan Error), yang kedua menangkap semua subclass dari Exception.

Error secara terprogram tidak dapat dipulihkan dengan cara apa pun dan biasanya tidak ditangkap, kecuali untuk tujuan logging (yang melewatinya lagi). Exceptionterprogram dapat dipulihkan. Subkelasnya RuntimeExceptionmenunjukkan kesalahan pemrograman dan biasanya tidak ditangkap juga.

BalusC
sumber
37
Cukup luar biasa, 4 tahun setelah jawaban ini, sebagian besar alat "analisis kode" masih akan melaporkan tangkapan yang dapat dibuang sebagai kesalahan kritis . Penebangan adalah alasan yang sangat valid untuk menangkap Throwable. Bertahun-tahun mengembangkan server memberi tahu saya bahwa 1) Penebangan akan terjadi meskipun mendapatkan Errordan 2) Kecuali jika ada pencatatan, Anda mungkin tidak pernah diberi tahu bahwa OOM terjadi, membuat Anda bertanya-tanya mengapa server mulai berperilaku "lucu"
Bruno Grieder
4
Apa programmatically unrecoverablesebenarnya yang dimaksud? Apakah ini sangat parah, sehingga pada dasarnya kita tidak dapat memanggil metode Java APA SAJA setelah menangkapnya lagi (logging, dll) tanpa kesempatan untuk mendapatkan perilaku yang tidak terduga dari JVM sebagai hasilnya?
Alexander Abakumov
Its subclass RuntimeException indicates a programming error: Tidak yakin apakah saya setuju dengan pernyataan ini. Jika itu benar, itu berarti semua pengecualian yang diharapkan harus diperiksa pengecualian. Bagaimana jika saya mengharapkan sesuatu mungkin gagal dan tidak dapat dipulihkan oleh aplikasi saya, tetapi saya ingin setidaknya melemparkan pengecualian yang bermakna? Menggunakan pengecualian yang diperiksa dalam kasus itu tampaknya tidak berguna dan membuat kode boilerplate.
Nom1fan
22

Thowablebenar-benar menangkap semuanya, bahkan ThreadDeath yang dilemparkan secara default untuk menghentikan utas dari metode yang sekarang tidak Thread.stop()digunakan lagi . Jadi dengan menangkap ThrowableAnda dapat yakin bahwa Anda tidak akan pernah meninggalkan blok percobaan tanpa setidaknya melewati blok tangkapan Anda, tetapi Anda harus siap untuk juga menangani OutOfMemoryErrordan InternalErroratau StackOverflowError.

Menangkap Throwablesangat berguna untuk loop server luar yang mendelegasikan semua jenis permintaan ke kode luar tetapi mungkin sendiri tidak pernah berakhir untuk menjaga layanan tetap hidup.

x4u
sumber
21

Throwableadalah kelas super Exceptionjuga Error. Dalam kasus normal kita harus selalu menangkap sub-kelasException , sehingga akar permasalahan tidak hilang.

Hanya kasus khusus di mana Anda melihat kemungkinan kesalahan terjadi yang tidak dapat mengontrol kode Java Anda, Anda harus menangkap Erroratau Throwable.

Saya ingat menangkap Throwable untuk menandai bahwa perpustakaan asli tidak dimuat.

rai.skumar
sumber
0

Saya telah melihat orang menggunakan Throwable untuk menangkap beberapa kesalahan yang mungkin terjadi karena kegagalan infra / ketersediaan.

Tombak A1
sumber