Saya khawatir ini adalah pengecualian waktu proses sehingga mungkin harus digunakan dengan hemat.
Kasus penggunaan standar:
void setPercentage(int pct) {
if( pct < 0 || pct > 100) {
throw new IllegalArgumentException("bad percent");
}
}
Tapi sepertinya itu akan memaksa desain berikut:
public void computeScore() throws MyPackageException {
try {
setPercentage(userInputPercent);
}
catch(IllegalArgumentException exc){
throw new MyPackageException(exc);
}
}
Untuk mengembalikannya menjadi pengecualian yang dicentang.
Oke, tapi mari kita lakukan itu. Jika Anda memberikan input yang buruk, Anda akan mendapatkan error runtime. Jadi pertama-tama, itu sebenarnya kebijakan yang cukup sulit untuk diterapkan secara seragam, karena Anda dapat melakukan konversi yang sangat berlawanan:
public void scanEmail(String emailStr, InputStream mime) {
try {
EmailAddress parsedAddress = EmailUtil.parse(emailStr);
}
catch(ParseException exc){
throw new IllegalArgumentException("bad email", exc);
}
}
Dan lebih buruk - saat memeriksa 0 <= pct && pct <= 100
kode klien dapat diharapkan untuk dilakukan secara statis, ini tidak berlaku untuk data yang lebih canggih seperti alamat email, atau lebih buruk, sesuatu yang harus diperiksa terhadap database, oleh karena itu secara umum kode klien tidak dapat digunakan sebelumnya. mengesahkan.
Jadi pada dasarnya apa yang saya katakan adalah saya tidak melihat kebijakan konsisten yang berarti untuk digunakan IllegalArgumentException
. Tampaknya itu tidak boleh digunakan dan kami harus tetap berpegang pada pengecualian kami sendiri. Apa kasus penggunaan yang baik untuk membuang ini?
sumber
Ketika berbicara tentang "masukan yang buruk", Anda harus mempertimbangkan dari mana masukan itu berasal.
Apakah input yang dimasukkan oleh pengguna atau sistem eksternal lain yang tidak Anda kontrol, Anda harus mengharapkan input tersebut tidak valid, dan selalu memvalidasinya. Dalam kasus ini, tidak masalah untuk menampilkan pengecualian yang dicentang. Aplikasi Anda harus 'pulih' dari pengecualian ini dengan memberikan pesan kesalahan kepada pengguna.
Jika masukan berasal dari sistem Anda sendiri, misalnya database Anda, atau beberapa bagian lain dari aplikasi Anda, Anda harus dapat mengandalkannya agar valid (seharusnya sudah divalidasi sebelum sampai di sana). Dalam kasus ini, tidak masalah untuk menampilkan pengecualian yang tidak dicentang seperti IllegalArgumentException, yang tidak boleh ditangkap (secara umum Anda tidak boleh menangkap pengecualian yang tidak dicentang). Ini adalah kesalahan programmer bahwa nilai yang tidak valid sampai di sana sejak awal;) Anda harus memperbaikinya.
sumber
Because an unchecked exception is meant to be thrown as a result of a programming error
membantu saya menjernihkan banyak hal di kepala saya, terima kasih :)Melempar pengecualian waktu proses "dengan hemat" sebenarnya bukan kebijakan yang baik - Java yang efektif merekomendasikan agar Anda menggunakan pengecualian yang dicentang saat pemanggil dapat diharapkan pulih secara wajar . (Kesalahan programmer adalah contoh khusus: jika kasus tertentu menunjukkan kesalahan programmer, maka Anda harus memberikan pengecualian yang tidak dicentang; Anda ingin programmer memiliki jejak tumpukan di mana masalah logika terjadi, bukan mencoba menanganinya sendiri.)
Jika tidak ada harapan untuk pulih, silakan gunakan pengecualian yang tidak dicentang; tidak ada gunanya menangkap mereka, jadi tidak apa-apa.
Tidak 100% jelas dari contoh Anda kasus mana contoh ini ada dalam kode Anda.
sumber
foo(data)
bisa saja terjadi sebagai bagianfor(Data data : list) foo(data);
di mana pemanggil ingin sebanyak mungkin berhasil meskipun beberapa data salah format. Termasuk kesalahan program juga, jika aplikasi saya gagal berarti transaksi tidak akan berjalan, itu mungkin lebih baik, jika itu berarti pendinginan nuklir menjadi offline itu buruk.StackOverflowError
dan kasus-kasus di mana penelepon tidak dapat diharapkan pulih secara wajar. Tapi sepertinya kasus level logika data atau aplikasi harus diperiksa. Itu berarti lakukan pemeriksaan penunjuk nol Anda!Sebagaimana ditentukan dalam tutorial resmi oracle, dinyatakan bahwa:
Jika saya memiliki Aplikasi yang berinteraksi dengan database menggunakan
JDBC
, Dan saya memiliki metode yang mengambil argumen sebagaiint item
dandouble price
. Untukprice
item yang sesuai dibaca dari tabel database. Saya hanya mengalikan jumlah total yangitem
dibeli denganprice
nilainya dan mengembalikan hasilnya. Meskipun saya selalu yakin di akhir saya (Aplikasi akhir) bahwa nilai bidang harga di tabel tidak akan pernah negatif. Tetapi bagaimana jika nilai harga keluar negatif ? Ini menunjukkan bahwa ada masalah serius dengan sisi database. Mungkin salah memasukkan harga oleh operator. Ini adalah jenis masalah yang tidak dapat diantisipasi dan tidak dapat dipulihkan oleh bagian lain dari aplikasi yang memanggil metode itu. Ini adaBUG
di database Anda. Jadi, danIllegalArguementException()
harus dilemparkan dalam kasus ini yang akan menyatakan ituthe price can't be negative
.Saya harap saya telah mengungkapkan maksud saya dengan jelas ..
sumber
API apa pun harus memeriksa validitas setiap parameter metode publik apa pun sebelum menjalankannya:
Mereka mewakili 99.9% dari kali kesalahan dalam aplikasi karena meminta operasi yang tidak mungkin sehingga pada akhirnya mereka adalah bug yang seharusnya merusak aplikasi (jadi ini adalah kesalahan yang tidak dapat dipulihkan).
Dalam kasus ini dan mengikuti pendekatan cepat gagal, Anda harus membiarkan aplikasi selesai untuk menghindari kerusakan status aplikasi.
sumber
Perlakukan
IllegalArgumentException
sebagai pemeriksaan prasyarat , dan pertimbangkan prinsip desain: Sebuah metode publik harus mengetahui dan secara publik mendokumentasikan prasyaratnya sendiri.Saya setuju contoh ini benar:
Jika EmailUtil tidak tembus pandang , artinya ada beberapa alasan prasyarat tidak dapat dijelaskan kepada pengguna akhir, maka pengecualian yang dicentang benar. Versi kedua, dikoreksi untuk desain ini:
Jika EmailUtil transparan , misalnya mungkin itu adalah metode privat yang dimiliki oleh kelas di bawah pertanyaan,
IllegalArgumentException
benar jika dan hanya jika prasyaratnya dapat dijelaskan dalam dokumentasi fungsi. Ini adalah versi yang benar juga:Desain ini bisa berjalan baik.
ParseException
. Metode tingkat atas di sini dinamaiscanEmail
yang mengisyaratkan pengguna akhir bermaksud untuk mengirim email yang belum dipelajari sehingga kemungkinan ini benar.IllegalArgumentException
. Meskipun tidak "dicentang", "centang" berpindah ke Javadoc yang mendokumentasikan fungsi, yang diharapkan dipatuhi oleh klien.IllegalArgumentException
di mana klien tidak dapat mengatakan argumen mereka sebelumnya ilegal adalah salah.Catatan tentang IllegalStateException : Ini berarti "status internal objek ini (variabel instance pribadi) tidak dapat melakukan tindakan ini." Pengguna akhir tidak dapat melihat status privat dengan begitu bebas sehingga lebih diutamakan
IllegalArgumentException
jika panggilan klien tidak memiliki cara untuk mengetahui status objek tidak konsisten. Saya tidak memiliki penjelasan yang baik ketika lebih disukai daripada pengecualian yang dicentang, meskipun hal-hal seperti menginisialisasi dua kali, atau kehilangan koneksi database yang tidak dipulihkan, adalah contohnya.sumber