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.
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.
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.
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.
Jawaban:
Dengan menangkap
Throwable
itu termasuk hal-hal yang subclassError
. 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.sumber
throw new Throwable();
, jadi itu adalah satu-satunya cara untuk benar-benar menangkap semuanya.Yang pertama menangkap semua subclass dari
Throwable
(ini termasukException
danError
), yang kedua menangkap semua subclass dariException
.Error
secara terprogram tidak dapat dipulihkan dengan cara apa pun dan biasanya tidak ditangkap, kecuali untuk tujuan logging (yang melewatinya lagi).Exception
terprogram dapat dipulihkan. SubkelasnyaRuntimeException
menunjukkan kesalahan pemrograman dan biasanya tidak ditangkap juga.sumber
Error
dan 2) Kecuali jika ada pencatatan, Anda mungkin tidak pernah diberi tahu bahwa OOM terjadi, membuat Anda bertanya-tanya mengapa server mulai berperilaku "lucu"programmatically unrecoverable
sebenarnya 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?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.Thowable
benar-benar menangkap semuanya, bahkan ThreadDeath yang dilemparkan secara default untuk menghentikan utas dari metode yang sekarang tidakThread.stop()
digunakan lagi . Jadi dengan menangkapThrowable
Anda dapat yakin bahwa Anda tidak akan pernah meninggalkan blok percobaan tanpa setidaknya melewati blok tangkapan Anda, tetapi Anda harus siap untuk juga menanganiOutOfMemoryError
danInternalError
atauStackOverflowError
.Menangkap
Throwable
sangat berguna untuk loop server luar yang mendelegasikan semua jenis permintaan ke kode luar tetapi mungkin sendiri tidak pernah berakhir untuk menjaga layanan tetap hidup.sumber
Throwable
adalah kelas superException
jugaError
. 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
Error
atauThrowable
.sumber
Saya telah melihat orang menggunakan Throwable untuk menangkap beberapa kesalahan yang mungkin terjadi karena kegagalan infra / ketersediaan.
sumber