JavaRush /Blog Java /Random-MS /Pengecualian: ditandai, dinyahtanda dan milik anda

Pengecualian: ditandai, dinyahtanda dan milik anda

Diterbitkan dalam kumpulan
hello! Dalam kuliah terakhir, kami membiasakan diri dengan aspek bahasa Jawa sebagai pengecualian dan melihat contoh bekerja dengannya. Hari ini kita akan melihat lebih mendalam pada struktur mereka, dan juga belajar cara menulis pengecualian kita sendiri :)

Jenis pengecualian

Seperti yang kami katakan, terdapat banyak kelas pengecualian di Jawa, hampir 400! Tetapi mereka semua dibahagikan kepada kumpulan, jadi agak mudah untuk mengingati mereka. Begini rupanya: Pengecualian: disemak, dinyahtanda dan milik anda sendiri - 2Semua pengecualian mempunyai kelas nenek moyang yang sama Throwable. Dua kumpulan besar datang daripadanya - pengecualian (Pengecualian) dan ralat (Ralat). Ralat ialah ralat kritikal semasa pelaksanaan program yang dikaitkan dengan pengendalian mesin maya Java. Dalam kebanyakan kes, Ralat tidak perlu dikendalikan, kerana ia menunjukkan beberapa kelemahan serius dalam kod. Ralat yang paling terkenal: StackOverflowError- berlaku, sebagai contoh, apabila kaedah tanpa henti memanggil dirinya sendiri, dan OutOfMemoryError- berlaku apabila tidak ada memori yang mencukupi untuk mencipta objek baharu. Seperti yang anda lihat, dalam situasi ini, selalunya tiada apa-apa yang istimewa untuk diproses - kod itu ditulis secara tidak betul dan perlu dibuat semula. Pengecualian , sebenarnya, pengecualian: situasi luar biasa, tidak dirancang yang berlaku semasa program sedang berjalan. Ini bukan ralat seserius Ralat, tetapi ia memerlukan perhatian kita. Semua pengecualian dibahagikan kepada 2 jenis - ditanda ( ditanda ) dan tidak ditanda ( ditanda ). Pengecualian: disemak, dinyahtanda dan milik anda sendiri - 3Semua pengecualian yang diperiksa datang daripada Exception. Apakah maksud "boleh disahkan"? Kami menyebut sebahagiannya dalam kuliah terakhir : "... pengkompil Java mengetahui tentang pengecualian yang paling biasa, dan mengetahui dalam situasi apa yang boleh berlaku." Sebagai contoh, dia tahu bahawa jika seorang pengaturcara membaca data daripada fail dalam kod, keadaan boleh timbul dengan mudah bahawa fail itu tidak wujud. Dan terdapat banyak situasi sedemikian yang boleh dia jangkakan terlebih dahulu. Oleh itu, pengkompil menyemak kod kami terlebih dahulu untuk kemungkinan pengecualian. Jika ia menemuinya, ia tidak akan menyusun kod tersebut sehingga kami memprosesnya atau memajukannya ke atas. Jenis pengecualian kedua ialah "tidak ditandai". Mereka datang dari kelas RuntimeException. Bagaimanakah mereka berbeza daripada yang diuji? Nampaknya terdapat juga sekumpulan kelas berbeza yang datang RuntimeExceptiondan menerangkan pengecualian masa jalan tertentu. Perbezaannya ialah pengkompil tidak mengharapkan ralat ini. Dia seolah-olah berkata: "Pada masa menulis kod, saya tidak menemui apa-apa yang mencurigakan, tetapi ada masalah semasa ia berfungsi. Rupa-rupanya terdapat ralat dalam kod!” Dan memang begitu. Pengecualian yang tidak disemak selalunya adalah hasil daripada ralat pengaturcara. Dan pengkompil jelas tidak dapat menyediakan semua kemungkinan situasi tidak betul yang orang boleh buat dengan tangan mereka sendiri :) Oleh itu, ia tidak akan menyemak pengendalian pengecualian tersebut dalam kod kami. Anda telah pun menemui beberapa pengecualian yang tidak ditandakan:
  • ArithmeticExceptionberlaku apabila dibahagikan dengan sifar
  • ArrayIndexOutOfBoundsExceptionBerlaku apabila cuba mengakses sel di luar tatasusunan.
Secara teorinya, sudah tentu, pencipta Java boleh memperkenalkan pengendalian mandatori pengecualian sedemikian, tetapi apakah kod itu kemudian? Dengan sebarang operasi membahagi nombor, anda perlu menulis tangkapan cuba untuk memeriksa sama ada anda membahagi dengan sifar secara tidak sengaja? Setiap kali mengakses tatasusunan, anda perlu menulis tangkapan cuba untuk menyemak sama ada anda telah melampaui had ini. Sebarang kod yang ditulis akan menjadi spageti dan tidak boleh dibaca sepenuhnya. Adalah logik bahawa idea ini telah ditinggalkan. Oleh itu, pengecualian yang tidak ditandai tidak perlu dikendalikan dalam blok cuba-tangkap atau dilemparkan ke atas, walaupun ini secara teknikal mungkin, seperti Ralat.

Bagaimana untuk membuang pengecualian anda

Sudah tentu, pencipta Java tidak dapat menyediakan semua situasi luar biasa yang mungkin timbul dalam program. Terdapat terlalu banyak program di dunia, dan ia terlalu berbeza. Tetapi tidak mengapa, kerana anda boleh membuat pengecualian anda sendiri jika perlu. Ini dilakukan dengan sangat mudah. Anda hanya perlu membuat kelas anda sendiri. Namanya mesti berakhir dengan "Pengecualian". Pengkompil tidak memerlukan ini, tetapi pengaturcara yang membaca kod anda akan segera memahami bahawa ini adalah kelas pengecualian. Di samping itu, anda perlu menunjukkan bahawa kelas itu berasal dari kelas Exception. Ini sudah diperlukan untuk pengkompil dan operasi yang betul. Sebagai contoh, kami mempunyai kelas Dog - Dog. Kita boleh berjalan anjing menggunakan walk(). Tetapi sebelum itu, kita perlu menyemak sama ada haiwan peliharaan kita memakai kolar, tali dan muncung. Jika mana-mana daripada ini tiada, kami akan membuang pengecualian kami sendiri DogIsNotReadyException. Kodnya akan kelihatan seperti ini:
public class DogIsNotReadyException extends Exception {

   public DogIsNotReadyException(String message) {
       super(message);
   }
}
Untuk menunjukkan bahawa kelas adalah pengecualian, anda perlu menulis extends Exception selepas nama kelas: ini bermakna "kelas itu berasal daripada kelas Exception." Dalam pembina, kami hanya akan memanggil pembina kelas Exceptiondengan baris message- ia akan memaparkan kepada pengguna mesej daripada sistem yang menerangkan ralat yang telah berlaku. Inilah yang akan kelihatan 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("Let's go for a walk!");
   if (isCollarPutOn && isLeashPutOn && isMuzzlePutOn) {
       System.out.println("Hurrah, let's go for a walk!" + name + " I am glad!");
   } else {
       throw new DogIsNotReadyException("Dog " + name + "not ready for a walk! Check your gear!");
   }
 }

}
Sekarang kaedah kami walk()membuang pengecualian DogIsNotReadyException. Ini dilakukan menggunakan kata kunci throw. Seperti yang kami katakan sebelum ini, pengecualian adalah objek. Oleh itu, dalam kaedah kami, apabila situasi luar biasa berlaku - ada sesuatu yang hilang pada anjing itu - kami mencipta objek kelas baharu DogIsNotReadyExceptiondan membuangnya ke dalam program menggunakan perkataan throw. walk()Kami menambah lontaran pada tandatangan kaedah DogIsNotReadyException. Dalam erti kata lain, pengkompil kini sedar bahawa panggilan kaedah walk()boleh menyebabkan pengecualian. Jadi apabila kita memanggil ini di suatu tempat dalam program, pengecualian perlu dikendalikan. Mari cuba lakukan ini dalam kaedah main():
public static void main(String[] args) {

   Dog dog = new Dog("Mukhtar");
   dog.putCollar();
   dog.putMuzzle();
   dog.walk();//Unhandled exception: DogIsNotReadyException
}
Tidak menyusun, pengecualian tidak dikendalikan! Mari bungkus kod kami dalam blok try-catchuntuk mengendalikan pengecualian:
public static void main(String[] args) {

   Dog dog = new Dog("Mukhtar");
   dog.putCollar();
   dog.putMuzzle();
   try {
       dog.walk();
   } catch (DogIsNotReadyException e) {
       System.out.println(e.getMessage());
       System.out.println("Checking equipment! Is the collar on?" + dog.isCollarPutOn + "\r\n Is the leash on?"
       + dog.isLeashPutOn + "\r\n Are you wearing a muzzle?" + dog.isMuzzlePutOn);
   }
}
Sekarang mari kita lihat output konsol:

Ошейник надет! 
Намордник надет! 
Собираемся на прогулку! 
Собака Мухтар не готова к прогулке! Проверьте экипировку! 
Проверяем снаряжение! Ошейник надет? true
Поводок надет? false 
Намордник надет? true
Lihatlah betapa lebih bermaklumat output konsol telah menjadi! Kami melihat setiap langkah yang berlaku dalam program; Kami melihat di mana ralat itu berlaku dan segera perasan apa sebenarnya anjing kami hilang :) Beginilah cara kami mencipta pengecualian kami sendiri. Seperti yang anda lihat, tiada yang rumit. Dan walaupun pembangun Java tidak peduli untuk menambah pengecualian khas pada bahasa mereka untuk anjing yang tidak dilengkapi dengan betul, kami membetulkan kesilapan mereka :)
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION