Cara Menangani Pengecualian Java dengan Cara yang Betul

Cara Menangani Pengecualian Java dengan Cara yang Betul

Sebagai pemula pengaturcaraan, konsep pengendalian pengecualian sukar untuk membungkus kepala anda. Bukan bahawa konsep itu sendiri sukar, tetapi terminologi dapat membuatnya kelihatan lebih maju daripada yang sebenarnya. Dan ciri yang sangat hebat sehingga terdedah kepada penyalahgunaan dan penyalahgunaan.





Dalam artikel ini, anda akan mengetahui apa pengecualian, mengapa mereka penting, cara menggunakannya, dan kesilapan biasa yang harus dielakkan. Sebilangan besar bahasa moden mempunyai beberapa jenis pengecualian, jadi jika anda berpindah dari Java, anda boleh mengambil sebahagian besar petua ini.





Memahami Pengecualian Java

Di Jawa, sebuah pengecualian adalah objek yang menunjukkan sesuatu yang tidak normal (atau 'luar biasa') berlaku semasa aplikasi anda dijalankan. Pengecualian tersebut adalah dilemparkan , yang pada dasarnya bermaksud objek pengecualian dibuat (serupa dengan bagaimana kesalahan 'dibangkitkan').





Keindahannya adalah anda boleh tangkap dilemparkan pengecualian, yang membolehkan anda menangani keadaan tidak normal dan membiarkan aplikasi anda terus berjalan seolah-olah tidak ada yang salah. Sebagai contoh, sedangkan penunjuk nol di C mungkin menghancurkan aplikasi anda, Java memungkinkan anda membuang dan menangkap

NullPointerException

s sebelum pemboleh ubah nol berpeluang menyebabkan kemalangan.



Ingat, pengecualian hanyalah objek, tetapi dengan satu ciri penting: ia mesti dilanjutkan dari

Exception

kelas atau mana-mana subkelas dari





Exception

. Walaupun Java mempunyai semua jenis pengecualian bawaan, anda juga dapat membuat sendiri jika anda inginkan. Sesetengah pengecualian Java yang paling biasa merangkumi:

  • NullPointerException
  • NumberFormatException
  • IllegalArgumentException
  • RuntimeException
  • IllegalStateException

Jadi apa yang berlaku apabila anda membuang pengecualian?





Pertama, Java melihat dalam kaedah segera untuk melihat apakah ada kod yang menangani jenis pengecualian yang anda lemparkan. Sekiranya pengendali tidak ada, ia akan melihat kaedah yang memanggil kaedah semasa untuk melihat apakah pegangan ada di sana. Sekiranya tidak, ia melihat kaedah yang dipanggil itu kaedah, dan kemudian kaedah seterusnya, dll. Sekiranya pengecualian tidak ditangkap, aplikasi mencetak jejak timbunan dan kemudian mogok. (Sebenarnya ia lebih bernuansa daripada sekadar meretas, tetapi itu adalah topik lanjutan di luar ruang lingkup artikel ini.)

KE jejak timbunan adalah senarai semua kaedah yang dilalui oleh Java semasa mencari pengendali pengecualian. Inilah rupa jejak timbunan:

Exception in thread 'main' java.lang.NullPointerException
at com.example.myproject.Book.getTitle(Book.java:16)
at com.example.myproject.Author.getBookTitles(Author.java:25)
at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

Kita dapat memperoleh banyak dari ini. Pertama, pengecualian yang dilemparkan adalah

NullPointerException

. Ia berlaku di

getTitle()

kaedah pada baris 16 Book.java. Kaedah itu dipanggil dari

getBookTitles()

di baris ke 25 Pengarang.java. Itu kaedah dipanggil dari

main()

di baris 14 Bootstrap.java. Seperti yang anda lihat, mengetahui semua ini menjadikan penyahpepijatan lebih mudah.

Tetapi sekali lagi, manfaat pengecualian yang sebenarnya adalah anda dapat 'menangani' keadaan tidak normal dengan menangkap pengecualian, menetapkan sesuatu dengan benar, dan menyambung semula aplikasi tanpa crash.

Menggunakan Pengecualian Java dalam Kod

Katakan anda mempunyai

someMethod()

yang memerlukan bilangan bulat dan melaksanakan beberapa logik yang boleh pecah jika bilangan bulat kurang dari 0 atau lebih besar daripada 100. Ini boleh menjadi tempat yang baik untuk membuang pengecualian:

apa itu wps pada penghala
public void someMethod(int value) {
if (value 100) {
throw new
IllegalArgumentException

Untuk mendapatkan pengecualian ini, anda perlu pergi ke mana

someMethod()

dipanggil dan menggunakan blok cubaan tangkapan :

public void callingMethod() {
try {
someMethod(200);
someOtherMethod();
} catch (IllegalArgumentException e) {
// handle the exception in here
}
// ...
}

Semua di dalam cuba blok akan dilaksanakan dengan teratur sehingga pengecualian dilemparkan. Sebaik sahaja pengecualian dilemparkan, semua pernyataan berikutnya dilangkau dan logik aplikasi segera melonjak ke tangkap sekatan.

Dalam contoh kami, kami memasukkan blok percubaan dan segera memanggil

someMethod()

. Oleh kerana 200 tidak antara 0 dan 100, an

IllegalArgumentException

dilemparkan. Ini segera menghentikan pelaksanaan

someMethod()

, melangkau logik selebihnya di blok cubaan (

someOtherMethod()

tidak pernah dipanggil), dan meneruskan pelaksanaan dalam blok tangkapan.

Apa yang akan berlaku sekiranya kita memanggil

someMethod(50)

sebaliknya? The

IllegalArgumentException

tidak akan dilemparkan.

someMethod()

akan dilaksanakan seperti biasa. Blok percubaan akan dijalankan seperti biasa, memanggil

someOtherMethod()

apabila beberapa Kaedah () selesai. Bila

someOtherMethod()

hujung, blok tangkapan akan dilangkau dan

callingMethod()

akan berterusan.

Perhatikan bahawa anda boleh mempunyai banyak blok tangkapan per blok percubaan:

public void callingMethod() {
try {
someMethod(200);
someOtherMethod();
} catch (IllegalArgumentException e) {
// handle the exception in here
} catch (NullPointerException e) {
// handle the exception in here
}
// ...
}

Perhatikan juga bahawa pilihan akhirnya blok ada juga:

public void method() {
try {
// ...
} catch (Exception e) {
// ...
} finally {
// ...
}
}

Kod dalam blok akhirnya adalah selalu dilaksanakan tidak kira apa. Sekiranya anda mempunyai pernyataan pengembalian dalam blok percubaan, blok akhirnya dilaksanakan sebelum kembali keluar dari kaedah. Sekiranya anda membuang pengecualian lain di blok tangkapan, blok akhirnya dilaksanakan sebelum pengecualian dilemparkan.

Anda harus menggunakan blok akhirnya apabila anda mempunyai objek yang perlu dibersihkan sebelum kaedah ini berakhir. Sebagai contoh, jika anda membuka fail di blok percubaan dan kemudian membuang pengecualian, blok akhirnya membolehkan anda menutup fail sebelum meninggalkan kaedah.

Perhatikan bahawa anda boleh mempunyai blok akhirnya tanpa blok tangkapan:

public void method() {
try {
// ...
} finally {
// ...
}
}

Ini membolehkan anda melakukan pembersihan yang diperlukan sambil membiarkan pengecualian dilemparkan untuk menyebarkan kaedah pemanggilan kaedah (iaitu anda tidak mahu menangani pengecualian di sini tetapi anda masih perlu membersihkannya terlebih dahulu).

Pengecualian Tercentang vs Tidak Diperiksa di Java

Tidak seperti kebanyakan bahasa, Java membezakan antara diperiksa pengecualian dan pengecualian yang tidak dicentang (mis. C # hanya mempunyai pengecualian yang tidak dicentang). Pengecualian yang diperiksa mesti terperangkap dalam kaedah di mana pengecualian dilemparkan atau jika tidak kod tidak akan disusun.

Untuk membuat pengecualian yang diperiksa, panjangkan dari

Exception

. Untuk membuat pengecualian yang tidak dicentang, panjangkan dari

RuntimeException

.

Mana-mana kaedah yang melontarkan pengecualian yang diperiksa mesti menunjukkan ini dalam kaedah tandatangan menggunakan balingan kata kunci. Sejak Java dibina

IOException

adalah pengecualian yang diperiksa, kod berikut tidak akan menyusun:

public void wontCompile() {
// ...
if (someCondition) {
throw new IOException();
}
// ...
}

Anda mesti menyatakan bahawa ia membuang pengecualian yang diperiksa:

public void willCompile() throws IOException {
// ...
if (someCondition) {
throw new IOException();
}
// ...
}

Perhatikan bahawa kaedah boleh dinyatakan sebagai membuang pengecualian tetapi tidak pernah membuang pengecualian. Walaupun begitu, pengecualian masih perlu ditangkap atau tidak kodnya akan disusun.

Bilakah anda harus menggunakan pengecualian yang dicentang atau tidak dicentang?

Dokumentasi Java rasmi mempunyai halaman mengenai soalan ini . Ini merangkum perbedaan dengan aturan praktis ringkas: 'Jika klien diharapkan dapat pulih dari pengecualian, jadikan pengecualian yang diperiksa. Sekiranya pelanggan tidak dapat melakukan apa-apa untuk pulih dari pengecualian, jadikannya pengecualian yang tidak dicentang. '

Tetapi garis panduan ini mungkin sudah ketinggalan zaman. Di satu pihak, pengecualian yang diperiksa menghasilkan kod yang lebih mantap. Sebaliknya, tidak ada bahasa lain yang memeriksa pengecualian dengan cara yang sama seperti Java, yang menunjukkan dua perkara: satu, ciri ini tidak cukup berguna untuk bahasa lain untuk mencurinya, dan dua, anda benar-benar dapat hidup tanpa mereka. Tambahan, pengecualian yang dicentang tidak bermain dengan baik dengan ungkapan lambda yang diperkenalkan di Java 8.

Garis Panduan Penggunaan Pengecualian Java

Pengecualian berguna tetapi mudah disalahgunakan dan disalahgunakan. Berikut adalah beberapa petua dan amalan terbaik untuk membantu anda mengelakkan daripada merosakkannya.

  • Lebih suka pengecualian khusus daripada pengecualian umum. Gunakan NumberFormatException lebih IllegalArgumentException jika boleh, sebaliknya gunakan IllegalArgumentException lebih RuntimeException bila boleh.
  • Jangan sekali-kali menangkap Throwable ! The Exception kelas sebenarnya meluas Throwable , dan blok tangkapan sebenarnya berfungsi dengan Throwable atau kelas yang meluas Throwable. Walau bagaimanapun, Error kelas juga meluas Throwable , dan anda tidak pernah mahu menangkap Error kerana Error s menunjukkan masalah serius yang tidak dapat dipulihkan.
  • Jangan sekali-kali menangkap Exception ! InterruptedException memanjang Exception , jadi mana-mana blok yang menangkap Exception juga akan menangkap InterruptedException , dan itu adalah pengecualian yang sangat penting yang anda tidak mahu main-main (terutamanya dalam aplikasi berbilang benang) melainkan anda tahu apa yang anda lakukan. Sekiranya anda tidak tahu pengecualian mana yang harus ditangkap, pertimbangkan untuk tidak menangkap apa-apa.
  • Gunakan mesej deskriptif untuk memudahkan penyahpepijatan. Apabila anda membuat pengecualian, anda boleh memberikan String mesej sebagai hujah. Mesej ini dapat diakses di blok tangkapan menggunakan Exception.getMessage() kaedah, tetapi jika pengecualian tidak pernah tertangkap, mesej itu juga akan muncul sebagai sebahagian daripada jejak timbunan.
  • Cuba jangan menangkap dan mengabaikan pengecualian. Untuk mengatasi kesulitan pengecualian yang diperiksa, banyak pengaturcara pemula dan pemalas akan menyiapkan blok tangkapan tetapi membiarkannya kosong. Buruk! Selalu mengatasinya dengan baik, tetapi jika anda tidak dapat, sekurang-kurangnya mencetak jejak timbunan sehingga anda tahu pengecualian dilemparkan. Anda boleh melakukan ini dengan menggunakan Exception.printStackTrace() kaedah.
  • Berhati-hati dengan pengecualian yang berlebihan. Apabila anda mempunyai tukul, semuanya kelihatan seperti paku. Semasa pertama kali mengetahui tentang pengecualian, anda mungkin merasa harus mengubah semuanya menjadi pengecualian ... ke titik di mana sebahagian besar aliran kawalan aplikasi anda menjadi pengendalian pengecualian. Ingat, pengecualian dimaksudkan untuk kejadian 'luar biasa'!

Sekarang anda harus cukup selesa dengan pengecualian untuk memahami apa itu, mengapa ia digunakan, dan bagaimana memasukkannya ke dalam kod anda sendiri. Sekiranya anda tidak memahami konsep sepenuhnya, tidak mengapa! Saya mengambil masa agak lama untuk 'mengklik' di kepala saya, jadi jangan merasa seperti anda perlu terburu-buru. Ambil masa anda.

Ada soalan? Tahu ada petua berkaitan pengecualian lain yang saya terlepas? Kongsi mereka dalam komen di bawah!

Berkongsi Berkongsi Tweet E-mel Cara Membuat Diagram Alir Data untuk Memvisualisasikan Data Setiap Projek

Diagram aliran data (DFD) sebarang proses membantu anda memahami bagaimana data mengalir dari sumber ke destinasi. Inilah cara membuatnya!

Baca Seterusnya
Topik-topik yang berkaitan
  • Pengaturcaraan
  • Jawa
Mengenai Pengarang Joel lee(1524 Artikel Diterbitkan)

Joel Lee adalah Ketua Editor MakeUseOf sejak tahun 2018. Dia mempunyai B.S. dalam Sains Komputer dan lebih dari sembilan tahun pengalaman menulis dan menyunting profesional.

bagaimana untuk mengetahui sama ada hdd anda hampir mati
Lagi Dari Joel Lee

Langgan buletin kami

Sertailah buletin kami untuk mendapatkan petua, ulasan, ebook percuma, dan tawaran eksklusif!

Klik di sini untuk melanggan