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 LeeLanggan buletin kami
Sertailah buletin kami untuk mendapatkan petua, ulasan, ebook percuma, dan tawaran eksklusif!
Klik di sini untuk melanggan