Apakah pernyataan kode ini setara? Apakah ada perbedaan di antara keduanya?
private void calculateArea() throws Exception {
....do something
}
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
Jawaban:
Ya, ada perbedaan besar - yang terakhir menelan pengecualian (menunjukkannya, memang), sedangkan yang pertama akan membiarkannya menyebar. (Saya berasumsi bahwa
showException
itu tidak mengulanginya.)Jadi jika Anda memanggil metode pertama dan "melakukan sesuatu" gagal, pemanggil harus menangani pengecualian. Jika Anda memanggil metode kedua dan "melakukan sesuatu" gagal, maka pemanggil tidak akan melihat pengecualian sama sekali ... yang umumnya merupakan hal yang buruk, kecuali
showException
telah benar-benar menangani pengecualian tersebut, memperbaiki apa pun yang salah, dan secara umum memastikan yangcalculateArea
telah mencapai tujuannya.Anda akan dapat mengatakan ini, karena Anda tidak dapat memanggil metode pertama tanpa baik menangkap
Exception
sendiri atau menyatakan bahwa metode Anda mungkin membuangnya juga.sumber
Yang pertama
throws Exception
, jadi penelepon harus menanganiException
. Yang kedua menangkap dan menangani secaraException
internal, sehingga pemanggil tidak perlu melakukan penanganan pengecualian apa pun.sumber
Iya. Versi yang mendeklarasikan
throws Exception
akan membutuhkan kode panggilan untuk menangani pengecualian, sedangkan versi yang secara eksplisit menanganinya tidak akan.yaitu, secara sederhana:
vs. memindahkan beban penanganan pengecualian ke pemanggil:
sumber
Ya, ada banyak sekali perbedaan di antara keduanya. Di blok kode pertama, Anda meneruskan pengecualian ke kode panggilan. Di blok kode kedua Anda menanganinya sendiri. Metode mana yang benar bergantung sepenuhnya pada apa yang Anda lakukan. Dalam beberapa kasus, Anda ingin kode Anda menangani pengecualian (jika file tidak ditemukan dan Anda ingin membuatnya, misalnya) tetapi dalam kasus lain, Anda ingin kode panggilan menangani pengecualian (file tidak ditemukan dan mereka perlu menentukan yang baru atau membuatnya).
Secara umum juga, Anda tidak ingin menangkap pengecualian umum. Alih-alih, Anda hanya ingin menangkap yang spesifik, seperti
FileNotFoundException
atauIOException
karena itu dapat memiliki arti yang berbeda.sumber
Ada satu skenario tertentu di mana kita tidak bisa menggunakan lemparan, kita harus menggunakan coba-tangkap. Ada aturan "Metode yang diganti tidak dapat menampilkan pengecualian tambahan apa pun selain yang dilontarkan oleh kelas induknya". Jika ada pengecualian ekstra yang harus ditangani menggunakan coba-tangkap. Pertimbangkan cuplikan kode ini. Ada kelas dasar yang sederhana
dan kelas turunannya:
Ketika kita harus memanggil thread.sleep () kita terpaksa menggunakan try-catch, disini kita tidak bisa menggunakan:
karena metode yang diganti tidak dapat mengeluarkan pengecualian ekstra.
sumber
Saya berasumsi bahwa dengan "identik" Anda mengacu pada perilaku.
Perilaku suatu fungsi dapat ditentukan oleh:
1) Nilai yang dikembalikan
2) Dilempar pengecualian
3) Efek samping (yaitu perubahan pada heap, sistem file, dll.)
Dalam kasus ini, metode pertama menyebarkan pengecualian apa pun, sedangkan metode kedua tidak melontarkan pengecualian yang dicentang, dan menelan sebagian besar pengecualian yang tidak dicentang juga, sehingga perilakunya berbeda.
Namun, jika Anda menjamin bahwa "melakukan sesuatu" tidak pernah memunculkan pengecualian, maka perilakunya akan sama (meskipun kompilator akan meminta pemanggil untuk menangani pengecualian tersebut, pada versi pertama)
--edit--
Dari sudut pandang desain API, metodenya sangat berbeda dalam kontraknya. Selain itu, melempar Exception kelas tidak disarankan. Coba lemparkan sesuatu yang lebih spesifik untuk memungkinkan penelepon menangani pengecualian dengan lebih baik.
sumber
Jika Anda melontarkan pengecualian, metode anak (yang menimpa ini) harus menangani pengecualian tersebut
contoh:
sumber
Sering kali Anda ingin penelepon menangani pengecualian. Misalkan Anda meminta pemanggil memanggil metode yang memanggil metode lain yang memanggil metode lain, alih-alih meminta setiap metode menangani pengecualian, Anda bisa menanganinya di pemanggil. Kecuali, Anda ingin melakukan sesuatu di salah satu metode ketika metode itu gagal.
sumber
Pemanggil metode ini perlu menangkap pengecualian ini atau mendeklarasikannya untuk dicabut kembali dalam tanda tangan metode itu.
Dalam contoh blok coba-tangkap di bawah ini. Pemanggil metode ini tidak perlu khawatir tentang menangani pengecualian karena sudah ditangani.
sumber
Ini melempar pengecualian, jadi pemanggil bertanggung jawab untuk menangani pengecualian itu tetapi jika pemanggil tidak menangani pengecualian tersebut maka mungkin itu akan diberikan ke jvm yang dapat mengakibatkan penghentian program yang tidak normal.
Sedangkan pada kasus kedua:
Di sini pengecualian ditangani oleh callee, jadi tidak ada kemungkinan penghentian program yang tidak normal.
Coba tangkap adalah pendekatan yang direkomendasikan.
IMO,
Melempar kata kunci yang paling sering digunakan dengan pengecualian Diperiksa untuk meyakinkan compiler tetapi tidak menjamin penghentian program secara normal.
Melempar kata kunci mendelegasikan tanggung jawab penanganan pengecualian ke
pemanggil (JVM atau metode lain).
Kata kunci lemparan diperlukan untuk pengecualian yang dicentang saja, untuk pengecualian yang tidak dicentang tidak ada penggunaan kata kunci lemparan.
sumber