Saya bekerja sebagai kontraktor yang merancang aplikasi Java perusahaan untuk klien saya dalam peran sebagai pimpinan teknis. Aplikasi akan digunakan oleh pengguna akhir dan akan ada tim pendukung yang akan mendukung aplikasi ketika kita pergi.
Petunjuk teknis lainnya dengan siapa saya bekerja berada di bawah kesan bahwa penanganan pengecualian akan membuat kode kotor. Sistem harus membuang pengecualian yang dicentang hanya dari tingkat Layanan dan sisa kode harus membuang pengecualian runtime dari semua tingkatan lainnya sehingga tidak perlu menangani pengecualian yang tidak dicentang.
Apa yang perlu dilemparkan dari pengecualian pada aplikasi bisnis?
Dari pengalaman saya di masa lalu tentang pengecualian runtime:
1) Pengecualian yang tidak dicentang membuat kode tidak dapat diprediksi karena tidak muncul bahkan di Javadoc.
2) Melempar Pengecualian yang tidak dicentang dalam aplikasi bisnis tidak masuk akal karena ketika Anda melemparkannya dan langsung masuk ke wajah Pengguna, bagaimana Anda menjelaskannya kepada pengguna? Saya sudah cukup banyak melihat aplikasi web yang menunjukkan 500 -Internal Error. Contact Administrator
apa-apa bagi pengguna akhir atau tim pendukung yang mengelola aplikasi.
3) Melempar pengecualian runtime memaksa pengguna kelas melempar pengecualian untuk berjalan melalui kode sumber untuk debug dan melihat mengapa pengecualian dilemparkan. Ini hanya dapat dihindari jika Javadoc dari pengecualian runtime didokumentasikan dengan sangat baik yang saya temukan tidak pernah menjadi kasus.
sumber
@throws
tag, yang merupakan praktik yang baik.@throws
tag Javadoc untuk mendokumentasikan setiap pengecualian yang tidak dicentang yang dapat dilempar suatu metode, tetapi jangan gunakan kata kunci lemparan untuk memasukkan pengecualian yang tidak dicentang dalam deklarasi metode.Jawaban:
Pengecualian yang dicentang adalah pengalaman gagal dalam desain bahasa. Mereka memaksa Anda untuk memiliki abstraksi yang sangat bocor dan kode kotor. Mereka harus dihindari sebisa mungkin.
Adapun poin Anda:
1) Pengecualian yang diperiksa membuat kode menjadi kotor, dan tidak kurang tidak terduga karena muncul di mana - mana .
2) Bagaimana pengecualian diperiksa ditunjukkan kepada pengguna lebih baik? Satu-satunya perbedaan nyata antara pengecualian yang diperiksa dan yang tidak dicentang adalah teknis dan hanya memengaruhi kode sumber.
3) Pernah mendengar jejak stack? Mereka memberi tahu Anda dengan tepat di mana pengecualian dilemparkan, tidak peduli apakah itu dicentang atau tidak dicentang. Sebenarnya, pengecualian yang diperiksa cenderung lebih buruk untuk debugging karena sering dibungkus yang mengarah ke jejak tumpukan yang lebih lama dan lebih buruk, atau bahkan hilang sama sekali karena pembungkusnya dilakukan dengan salah.
Ada dua jenis pengecualian: yang terjadi "normal" dan biasanya ditangani sangat dekat dengan tempat terjadinya, dan yang benar-benar luar biasa dan dapat ditangani secara umum dalam lapisan yang sangat tinggi (cukup batalkan tindakan saat ini dan catat / tampilkan kesalahan).
Pengecualian diperiksa adalah upaya untuk menempatkan perbedaan ini ke dalam sintaks bahasa pada titik pengecualian didefinisikan. Masalah dengan ini adalah
sumber
SQLException extends Exception
berarti memilih untuk melemparSQLException
karena kesalahan berkaitan dengan akses DB secara otomatis berarti pengecualian diperiksa. Dan Anda dapat mendokumentasikan pengecualian yang tidak dicentang dalam komentar Javadoc. Berfungsi dengan baik untuk semua bahasa lainnya.Pandangan saya adalah bahwa jenis pengecualian apa yang dilemparkan bergantung pada apa yang dilakukan kode Anda.
Saya melempar pengecualian yang sudah diperiksa ketika saya berharap hal itu bisa terjadi cukup sering (misalnya, pengguna memasukkan data yang cerdik) dan saya mengharapkan kode panggilan untuk menangani situasi.
Saya melempar pengecualian yang tidak dicentang / runtime (tidak sesering dicentang) ketika saya memiliki situasi langka yang tidak saya harapkan ditangani oleh kode panggilan. Contohnya mungkin semacam kesalahan terkait memori aneh yang tidak pernah saya harapkan terjadi. Tidak dicentang adalah jenis kesalahan yang Anda harapkan untuk menjatuhkan aplikasi.
Tidak terkecuali akan muncul di depan pengguna tanpa tingkat dukungan. Bahkan jika itu hanya "tolong potong dan tempel dump kesalahan ini ke email". Tidak ada yang lebih menyebalkan bagi pengguna daripada diberi tahu bahwa ada kesalahan, tetapi tidak diberi rincian atau tindakan yang dapat mereka lakukan untuk memulai perbaikan.
Dugaan saya adalah bahwa filosofi yang Anda sebutkan berasal dari salah satu dari dua sumber:
sumber
Jika Anda tidak ingin pengecualian runtime yang tidak dicentang, lalu mengapa Anda menggunakan java? Ada kemungkinan pengecualian runtime hampir di mana-mana - terutama NullPointerException, ArithmeticException, pengecualian ArrayIndexOutOfBounds, dll.
Dan ketika Anda pernah membaca file log dari beberapa sistem J2EE, seperti, misalnya, instalasi SAP NetWeaver, Anda akan melihat bahwa pengecualian seperti itu terjadi setiap saat.
sumber
Ada beberapa aturan untuk penanganan pengecualian yang harus Anda ingat. Tetapi pertama-tama, Anda harus ingat bahwa pengecualian adalah bagian dari antarmuka yang diekspos oleh kode; mendokumentasikannya . Ini terutama penting ketika antarmuka adalah antarmuka publik, tentu saja, tetapi itu adalah ide yang sangat bagus di antarmuka pribadi juga.
Pengecualian hanya harus ditangani pada titik di mana kode dapat melakukan sesuatu yang masuk akal dengannya. Opsi penanganan terburuk adalah tidak melakukan apa-apa tentang mereka, yang seharusnya hanya dilakukan ketika itu adalah pilihan yang tepat. (Ketika saya memiliki situasi seperti itu dalam kode saya, saya memasukkan komentar untuk efek itu sehingga saya tahu tidak perlu khawatir tentang tubuh kosong.)
Pilihan terburuk kedua adalah melemparkan pengecualian yang tidak terkait tanpa yang asli terlampir sebagai penyebabnya. Masalahnya di sini adalah bahwa informasi dalam pengecualian asli yang akan memungkinkan diagnosis masalah hilang; Anda sedang menciptakan sesuatu yang tak dapat melakukan apa saja dengan (selain mengeluh bahwa “itu tidak bekerja”, dan kita semua tahu bagaimana kita membenci mereka laporan bug).
Jauh lebih baik adalah mencatat pengecualian. Itu memungkinkan seseorang mengetahui apa masalahnya dan memperbaikinya, tetapi Anda hanya harus mencatat pengecualian pada titik di mana masalah tersebut akan hilang atau dilaporkan melalui koneksi eksternal. Itu bukan karena penebangan lebih sering merupakan masalah besar, tetapi karena penebangan yang berlebihan berarti Anda hanya mendapatkan lebih banyak ruang tanpa menggunakan lebih banyak informasi. Setelah Anda mencatat pengecualian, Anda dapat melaporkan suatu précis kepada pengguna / klien dengan hati nurani yang baik (selama Anda juga menyertakan waktu pembuatan - atau pengidentifikasi korelasi lainnya - dalam laporan itu sehingga versi singkatnya dapat dicocokkan. dengan detail jika perlu).
Pilihan terbaik adalah, tentu saja, untuk sepenuhnya menangani pengecualian, berurusan dengan situasi kesalahan secara keseluruhan. Jika Anda bisa melakukan ini, lakukan saja! Bahkan mungkin berarti Anda bisa menghindari harus mencatat pengecualian.
Salah satu cara untuk menangani pengecualian adalah dengan melemparkan pengecualian lain yang menyediakan deskripsi tingkat tinggi dari masalah (misalnya, "
failed to initialize
" bukannya "index out of bounds
"). Ini adalah pola yang baik selama Anda tidak kehilangan informasi tentang penyebab pengecualian; gunakan pengecualian terperinci untuk menginisialisasicause
pengecualian tingkat lebih tinggi atau catat detailnya (seperti dibahas di atas). Logging paling tepat ketika Anda akan melewati batas antar-proses, seperti panggilan IPC, karena tidak ada jaminan bahwa kelas pengecualian level rendah akan hadir sama sekali di ujung koneksi yang lain. Menjaga sebagai penyebab terlampir adalah yang paling tepat ketika melewati batas internal.Pola lain yang Anda lihat adalah tangkapan-dan-lepas:
Ini adalah anti-pola kecuali Anda memiliki batasan jenis dari
catch
klausa lain yang berarti Anda tidak bisa membiarkan pengecualian melewati sendiri. Maka itu hanya fitur jelek dari Java.Tidak ada perbedaan nyata antara pengecualian yang diperiksa dan yang tidak dicentang selain fakta bahwa Anda harus menyatakan pengecualian yang diperiksa yang melintasi batas metode. Itu masih merupakan ide bagus untuk mendokumentasikan pengecualian yang tidak dicentang (dengan
@throws
komentar javadoc) jika Anda tahu mereka dilemparkan dengan sengaja oleh kode Anda. Jangan dengan sengaja melemparjava.lang.Error
atau subkelasnya (kecuali jika Anda sedang menulis implementasi JVM).Opini: Kasus kesalahan tak terduga selalu mewakili bug dalam kode Anda. Pengecualian yang dicek adalah cara untuk mengelola ancaman ini, dan di mana pengembang sengaja menggunakan pengecualian yang tidak dicentang sebagai cara untuk menghindari masalah penanganan kasus kesalahan, Anda sedang membangun banyak hutang teknis yang harus Anda selesaikan beberapa waktu jika Anda ingin kode yang kuat. Penanganan kesalahan yang ceroboh tidak profesional (dan melihat penanganan kesalahan adalah cara yang baik untuk menentukan seberapa baik programmer sebenarnya).
sumber
Saya pikir Anda HANYA harus melempar pengecualian diperiksa ketika aplikasi dapat pulih. Jadi, pengguna perpustakaan Anda harus menangkap pengecualian itu dan melakukan apa yang perlu dipulihkan. Hal lain harus tidak dicentang.
Sebagai contoh,
Jika aplikasi Anda memuat data baik dari file atau database. Kemudian,..
penelepon selalu dapat menangkap MissingDataFileException yang dicentang dan kemudian mencoba memuat data dari database.
sumber