1. Jenis pengecualian

Semua pengecualian dibahagikan kepada 4 jenis, yang sebenarnya merupakan kelas yang mewarisi satu sama lain.
Throwable
kelas
Kelas asas untuk semua pengecualian ialah Throwable
kelas. Kelas Throwable
mengandungi kod yang menulis timbunan panggilan semasa (jejak tindanan kaedah semasa) kepada tatasusunan. Kita akan belajar apa itu surih tindanan sedikit kemudian.
Operator lontaran hanya boleh menerima objek yang berasal dari Throwable
kelas. Dan walaupun anda secara teorinya boleh menulis kod seperti throw new Throwable();
, tiada siapa yang biasanya melakukan ini. Tujuan utama kelas Throwable
adalah untuk mempunyai kelas induk tunggal untuk semua pengecualian.
Error
kelas
Kelas pengecualian seterusnya ialah Error
kelas, yang mewarisi Throwable
kelas secara langsung. Mesin Java mencipta objek kelas Error
(dan keturunannya) apabila masalah serius telah berlaku . Contohnya, kerosakan perkakasan, memori tidak mencukupi, dsb.
Biasanya, sebagai pengaturcara, tiada apa yang boleh anda lakukan dalam situasi di mana ralat sedemikian (jenis yang patut Error
dilemparkan) telah berlaku dalam atur cara: ralat ini terlalu serius. Apa yang anda boleh lakukan ialah memberitahu pengguna bahawa program itu ranap dan/atau menulis semua maklumat yang diketahui tentang ralat pada log program.
Exception
kelas
Kelas Exception
dan RuntimeException
adalah untuk ralat biasa yang berlaku dalam pengendalian banyak kaedah. Matlamat setiap pengecualian yang dilemparkan adalah untuk ditangkap oleh catch
blok yang tahu cara mengendalikannya dengan betul.
Apabila kaedah tidak dapat menyelesaikan kerjanya atas sebab tertentu, ia harus segera memberitahu kaedah panggilan dengan membuang pengecualian jenis yang sesuai.
Dalam erti kata lain, jika pembolehubah adalah sama dengan null
, kaedah akan membuang NullPointerException
. Jika hujah yang salah dihantar kepada kaedah, ia akan membuang InvalidArgumentException
. Jika kaedah secara tidak sengaja membahagi dengan sifar, ia akan membuang ArithmeticException
.
RuntimeException
kelas
RuntimeExceptions
ialah subset daripada Exceptions
. Kita juga boleh mengatakan bahawa RuntimeException
ia adalah versi ringan bagi pengecualian biasa ( Exception
) — lebih sedikit keperluan dan sekatan dikenakan ke atas pengecualian tersebut
Anda akan mengetahui perbezaan antara Exception
dan RuntimeException
kemudian.
2. Throws
: pengecualian diperiksa

Semua pengecualian Java jatuh ke dalam 2 kategori: ditandai dan dinyahtanda .
Semua pengecualian yang mewarisi RuntimeException
atau Error
dianggap pengecualian tidak ditanda . Semua yang lain disemak pengecualian .
Dua puluh tahun selepas pengecualian yang diperiksa diperkenalkan, hampir setiap pengaturcara Java menganggap ini sebagai pepijat. Dalam rangka kerja moden yang popular, 95% daripada semua pengecualian tidak ditandai. Bahasa C#, yang hampir menyalin Java dengan tepat, tidak menambah pengecualian yang diperiksa .
Apakah perbezaan utama antara pengecualian yang disemak dan tidak disemak ?
Terdapat keperluan tambahan yang dikenakan ke atas pengecualian yang disemak . Secara kasarnya, mereka adalah ini:
Keperluan 1
Jika kaedah melemparkan pengecualian yang ditandai , ia mesti menunjukkan jenis pengecualian dalam tandatangannya . Dengan cara itu, setiap kaedah yang memanggilnya menyedari bahawa "pengecualian yang bermakna" ini mungkin berlaku di dalamnya.
Nyatakan pengecualian yang disemak selepas parameter kaedah selepas throws
kata kunci (jangan gunakan throw
kata kunci secara tidak sengaja). Ia kelihatan seperti ini:
type method (parameters) throws exception
Contoh:
pengecualian diperiksa | pengecualian tidak ditanda |
---|---|
|
|
Dalam contoh di sebelah kanan, kod kami membuang pengecualian yang tidak ditanda — tiada tindakan tambahan diperlukan. Dalam contoh di sebelah kiri, kaedah membuang pengecualian yang ditandai , jadi throws
kata kunci ditambahkan pada tandatangan kaedah bersama-sama dengan jenis pengecualian.
Jika kaedah menjangkakan untuk membuang berbilang pengecualian yang ditandakan , kesemuanya mesti dinyatakan selepas throws
kata kunci, dipisahkan dengan koma. Perintah itu tidak penting. Contoh:
public void calculate(int n) throws Exception, IOException
{
if (n == 0)
throw new Exception("n is null!");
if (n == 1)
throw new IOException("n is 1");
}
Keperluan 2
Jika anda memanggil kaedah yang telah menyemak pengecualian dalam tandatangannya, anda tidak boleh mengabaikan fakta bahawa kaedah itu membuangnya.
Anda mesti sama ada menangkap semua pengecualian tersebut dengan menambahkan catch
blok untuk setiap satu, atau dengan menambahkannya pada throws
klausa untuk kaedah anda.
Seolah-olah kita berkata, " Pengecualian ini sangat penting sehingga kita mesti menangkapnya. Dan jika kita tidak tahu cara mengendalikannya, maka sesiapa yang mungkin memanggil kaedah kita mesti dimaklumkan bahawa pengecualian tersebut boleh berlaku di dalamnya.
Contoh:
Bayangkan bahawa kita sedang menulis kaedah untuk mencipta dunia yang dihuni oleh manusia. Bilangan awal orang diluluskan sebagai hujah. Jadi kita perlu menambah pengecualian jika terdapat terlalu sedikit orang.
Mencipta Bumi | Catatan |
---|---|
|
Kaedah ini berpotensi membuang dua pengecualian yang diperiksa :
|
Panggilan kaedah ini boleh dikendalikan dalam 3 cara:
1. Jangan tangkap sebarang pengecualian
Ini paling kerap dilakukan apabila kaedah itu tidak tahu cara mengendalikan keadaan dengan betul.
Kod | Catatan |
---|---|
|
Kaedah panggilan tidak menangkap pengecualian dan mesti memberitahu orang lain tentangnya: ia menambahkannya pada klausanya throws sendiri |
2. Tangkap beberapa pengecualian
Kami menangani kesilapan yang boleh kami tangani. Tetapi yang kita tidak faham, kita buang ke kaedah panggilan. Untuk melakukan ini, kita perlu menambah nama mereka pada klausa lontaran:
Kod | Catatan |
---|---|
|
Pemanggil hanya menangkap satu pengecualian yang diperiksaLonelyWorldException — . Pengecualian lain mesti ditambahkan pada tandatangannya, menunjukkannya selepas throws kata kunci |
3. Tangkap semua pengecualian
Jika kaedah tidak membuang pengecualian kepada kaedah panggilan, maka kaedah panggilan sentiasa yakin bahawa semuanya berfungsi dengan baik. Dan ia tidak akan dapat mengambil sebarang tindakan untuk membetulkan situasi yang luar biasa.
Kod | Catatan |
---|---|
|
Semua pengecualian terperangkap dalam kaedah ini. Pemanggil akan yakin bahawa semuanya berjalan lancar. |
3. Menangkap pelbagai pengecualian
Pengaturcara sangat tidak suka menduplikasi kod. Mereka juga menghasilkan prinsip pembangunan yang sepadan — KERING : Jangan Ulangi Sendiri. Tetapi apabila mengendalikan pengecualian, terdapat keadaan yang kerap apabila try
blok diikuti oleh beberapa catch
blok dengan kod yang sama.
Atau mungkin terdapat 3 catch
blok dengan kod yang sama dan 2 catch
blok lagi dengan kod yang serupa. Ini adalah situasi standard apabila projek anda mengendalikan pengecualian secara bertanggungjawab.
Bermula dengan versi 7, dalam bahasa Java menambahkan keupayaan untuk menentukan pelbagai jenis pengecualian dalam satu catch
blok. Ia kelihatan lebih kurang seperti ini:
try
{
// Code where an exception might occur
}
catch (ExceptionType1 | ExceptionType2 | ExceptionType3 name)
{
// Exception handling code
}
Anda boleh mempunyai seberapa banyak catch
blok yang anda mahu. Walau bagaimanapun, satu catch
blok tidak boleh menentukan pengecualian yang mewarisi satu sama lain. Dengan kata lain, anda tidak boleh menulis catch ( Exception
| RuntimeException
e), kerana RuntimeException
kelas mewarisi Exception
.
GO TO FULL VERSION