CodeGym /Blog Java /rawak /Pengecualian: ditandai, dinyahtanda dan tersuai
John Squirrels
Tahap
San Francisco

Pengecualian: ditandai, dinyahtanda dan tersuai

Diterbitkan dalam kumpulan
Hai! Dalam pelajaran lepas, kami telah mengenali pengecualian dalam bahasa Jawa, dan melihat contoh cara bekerja dengannya. Hari ini kita akan melihat dengan lebih mendalam struktur pengecualian, dan belajar cara menulis pengecualian kita sendiri :)

Jenis pengecualian

Seperti yang kami katakan sebelum ini, terdapat banyak pengecualian di Jawa, hampir 400! Tetapi mereka semua dibahagikan kepada kumpulan, jadi agak mudah untuk mengingati mereka. Beginilah rupanya: Pengecualian: ditandai, dinyahtanda dan tersuai - 2 Semua pengecualian mempunyai nenek moyang yang sama dalam Throwablekelas. Dua kumpulan utama diperoleh daripadanya: pengecualian ( Pengecualian ) dan ralat ( Ralat ). Ralat - Ini mewakili ralat masa jalan kritikal yang berkaitan dengan pengendalian mesin maya Java. Dalam kebanyakan kes, Ralat tidak perlu dikendalikan, kerana ia menunjukkan beberapa kelemahan serius dalam kod. Yang paling terkenal ialah StackOverflowError (ini berlaku, sebagai contoh, apabila kaedah memanggil dirinya sendiri tanpa henti) dan OutOfMemoryError(ini berlaku apabila memori tidak mencukupi untuk mencipta objek baharu). Seperti yang anda boleh lihat, dalam situasi ini, biasanya tiada apa-apa untuk dikendalikan pada masa jalankan: kod tersebut ditulis secara tidak betul dan perlu diolah semula. Pengecualian - Ini mewakili, baik, pengecualian: situasi luar biasa, tidak dirancang yang berlaku semasa program sedang berjalan. Mereka tidak serius seperti Ralat, tetapi mereka masih memerlukan perhatian kita. Semua pengecualian dibahagikan kepada 2 jenis: ditandai dan tidak ditanda . Pengecualian: ditandai, dinyahtanda dan tersuai - 3 Semua pengecualian yang diperiksa diperoleh daripada Exceptionkelas. Apakah maksud "disemak"? Kami merujuk kepada perkara ini dalam pelajaran lepas: "Oleh itu, pengkompil Java mengetahui pengecualian yang paling biasa dan situasi di mana ia mungkin berlaku." Sebagai contoh, ia mengetahui bahawa jika kod membaca data daripada fail, fail itu mungkin tidak wujud dengan mudah. Dan terdapat banyak situasi sedemikian (yang boleh disimpulkan). Sehubungan itu, pengkompil menyemak kod kami terlebih dahulu untuk kehadiran kemungkinan pengecualian ini. Jika ia menjumpainya, ia tidak akan menyusun kod tersebut sehingga kami telah mengendalikannya atau membuangnya semula. Jenis pengecualian kedua ialah "tidak ditandai". Mereka berasal dari RuntimeExceptionkelas. Bagaimanakah ia berbeza daripada pengecualian yang disemak? Nampaknya terdapat juga banyak kelas berbeza yang diperolehiRuntimeException(yang menerangkan pengecualian masa jalan). Perbezaannya ialah pengkompil tidak menjangkakan ralat ini. Nampaknya berkata, "Apabila kod itu ditulis, saya tidak menjumpai apa-apa yang mencurigakan, tetapi ada sesuatu yang tidak kena semasa ia berjalan. Nampaknya, terdapat ralat dalam kod!" Dan sesungguhnya ini adalah benar. Pengecualian yang tidak disemak selalunya adalah hasil daripada ralat pengaturcara. Dan pengkompil jelas tidak dapat meramalkan setiap kemungkinan situasi buruk yang mungkin dibuat oleh orang dengan tangan mereka sendiri. :) Oleh itu, ia tidak menyemak sama ada pengecualian tersebut dikendalikan dalam kod kami. Anda telah pun menemui beberapa pengecualian yang tidak ditandakan:
  • ArithmeticException berlaku apabila membahagi dengan sifar
  • ArrayIndexOutOfBoundsException berlaku apabila anda cuba mengakses kedudukan di luar tatasusunan.
Sudah tentu, anda boleh bayangkan bahawa pencipta Java mungkin telah memperkenalkan pengendalian pengecualian mandatori, tetapi dalam kes ini kod itu akan menjadi terlalu rumit. Untuk sebarang operasi pembahagian, adakah anda perlu menulis try-catchblok untuk menyemak sama ada anda secara tidak sengaja dibahagikan dengan sifar? Pada bila-bila masa anda mengakses tatasusunan, anda perlu menulis try-catchblok untuk menyemak sama ada indeks anda di luar had. Semuanya akan menjadi kod spageti dan tidak boleh dibaca sepenuhnya. Masuk akal bahawa idea ini telah ditinggalkan. Akibatnya, pengecualian yang tidak ditandai tidak perlu dikendalikan dalam try-catchblok atau dilempar semula (walaupun ini secara teknikalnya mungkin, seperti Ralat).

Bagaimana untuk membuang pengecualian anda sendiri

Sudah tentu, pencipta Java tidak dapat meramalkan setiap situasi luar biasa yang mungkin timbul dalam program. Terdapat terlalu banyak program di dunia, dan ia terlalu pelbagai. Tetapi ini tidak perlu dibimbangkan, kerana anda boleh membuat pengecualian anda sendiri, jika perlu. Ini sangat mudah dilakukan. Apa yang anda perlu lakukan ialah mencipta kelas anda sendiri. Anda harus memastikan namanya berakhir dengan "Pengecualian". Pengkompil tidak memerlukan ini, tetapi pengaturcara lain yang membaca kod anda akan segera memahami bahawa ia adalah kelas pengecualian. Di samping itu, nyatakan bahawa kelas itu diwarisi daripada Exceptionkelas (pengkompil memerlukan ini). Sebagai contoh, katakan kita mempunyai Dogkelas. Kita boleh berjalan anjing menggunakanwalk()kaedah. Tetapi sebelum melakukan itu, kita perlu menyemak sama ada haiwan peliharaan kita memakai kolar, tali dan muncung. Jika mana-mana gear ini tiada, kami membuang pengecualian kami sendiri: DogIsNotReadyException . Kodnya kelihatan seperti ini:

public class DogIsNotReadyException extends Exception {

   public DogIsNotReadyException(String message) {
       super(message);
   }
}
Untuk menunjukkan bahawa kelas itu adalah pengecualian, anda perlu menulis " memanjangkan Pengecualian " selepas nama kelas (ini bermaksud "kelas itu berasal daripada kelas Pengecualian"). Dalam pembina, kami hanya memanggil pembina kelas dengan mesejException String (jika pengecualian berlaku, kami akan menunjukkan mesej, penerangan tentang ralat, kepada pengguna). Begini rupanya dalam kod kelas kami:

public class Dog {

   String name;
   boolean isCollarPutOn;
   boolean isLeashPutOn;
   boolean isMuzzlePutOn;


   public Dog(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

   }

   public void putCollar() {

       System.out.println("The collar is on!");
       this.isCollarPutOn = true;
   }

   public void putLeash() {

       System.out.println("The leash is on!");
       this.isLeashPutOn = true;
   }

   public void putMuzzle() {
       System.out.println("The muzzle is on!");
       this.isMuzzlePutOn = true;
   }

   public void walk() throws DogIsNotReadyException {

   System.out.println("We're getting ready for a walk!");
   if (isCollarPutOn && isLeashPutOn && isMuzzlePutOn) {
       System.out.println("Hooray, let's go for a walk! " + name + " is very happy!");
   } else {
       throw new DogIsNotReadyException(name + " is not ready for a walk! Check the gear!");
   }
 }

}
Sekarang walk()kaedah kami membuang DogIsNotReadyException . Ini dilakukan dengan melontar kata kunci. Seperti yang kami katakan sebelum ini, pengecualian adalah objek. Jadi, apabila pengecualian berlaku (anjing itu kehilangan sesuatu) dalam kaedah kami, kami mencipta DogIsNotReadyExceptionobjek baharu dan membuangnya menggunakan lontaran kata kunci. Kami menambah " melempar DogIsNotReadyException " pada pengisytiharan kaedah. Dalam erti kata lain, kini pengkompil sedar bahawa memanggil walk()kaedah boleh bertukar menjadi situasi yang luar biasa. Sehubungan itu, pengecualian ini mesti dikendalikan jika kami memanggil kaedah ini di suatu tempat dalam program kami. Mari cuba lakukan ini dalam main()kaedah:

public static void main(String[] args) {
  
   Dog dog = new Dog("Buddy");
   dog.putCollar();
   dog.putMuzzle();
   dog.walk();// Unhandled exception: DogIsNotReadyException
}
Ini tidak akan disusun. Pengecualian tidak dikendalikan! Kami membungkus kod kami dalam try-catchblok untuk mengendalikan pengecualian:

public static void main(String[] args) {

   Dog dog = new Dog("Buddy");
   dog.putCollar();
   dog.putMuzzle();
   try {
       dog.walk();
   } catch (DogIsNotReadyException e) {
       System.out.println(e.getMessage());
       System.out.println("Checking the gear! Is the collar on? " + dog.isCollarPutOn + "\r\n Is the leash on? "
       + dog.isLeashPutOn + "\r\n Is the muzzle on? " + dog.isMuzzlePutOn);
   }
}
Sekarang mari kita lihat output konsol: Kolar dihidupkan! Muncung dihidupkan! Kami sedang bersiap untuk berjalan-jalan! Buddy belum bersedia untuk berjalan-jalan! Periksa gear! Memeriksa gear! Kolar dah pakai? benar Adakah tali terpasang? palsu Adakah muncung dihidupkan? benar Lihatlah betapa lebih bermaklumat keluaran konsol itu! Kami melihat setiap langkah yang diambil dalam program ini; kita melihat di mana ralat itu berlaku, dan kita juga boleh segera melihat apa yang hilang oleh anjing kita. :) Dan begitulah cara anda mencipta pengecualian anda sendiri. Seperti yang anda lihat, tidak ada yang rumit mengenainya. Dan walaupun pencipta Java tidak peduli untuk memasukkan dalam bahasa itu pengecualian khas untuk anjing yang kurang kelengkapan, kami telah membetulkan pengawasan mereka. :)
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION