JavaRush /Java Blog /Random-TK /Java-da kadadan çykmalar: tutmak we işlemek

Java-da kadadan çykmalar: tutmak we işlemek

Toparda çap edildi
Salam! Muny size bermegi ýigrenýärin, ýöne programmistiň işiniň uly bölegi ýalňyşlyklar bilen baglanyşykly. Köplenç - özleri bilen. Justalňyşmaýan adamlar ýok ýaly bolup geçýär. Şeýle programmalar hem ýok. Elbetde, ýalňyşlygyň üstünde işleýän wagtyňyz esasy zat, onuň sebäbine düşünmekdir. Programmada munuň üçin bir topar sebäpler bolup biler. Bir gezek “Java” döredijileri bir sorag bilen ýüzbe-ýüz boldular: programmalardaky bu ähtimal ýalňyşlyklar bilen näme etmeli? Olardan doly gaça durmak mümkin däl. Programmistler göz öňüne getirip bolmajak bir zat ýazyp bilerler :) Bu, ýalňyşlyklar bilen iş salyşmagyň mehanizmini dile girizmegiň zerurdygyny aňladýar. Başgaça aýdylanda, programmada käbir ýalňyşlyk ýüze çykan bolsa, has köp işlemek üçin skript gerek. Erroralňyşlyk ýüze çykanda programma takyk näme etmeli? Bu gün bu mehanizm bilen tanyşarys. Oňa “kadadan çykmalar ” diýilýär .

Java-da kadadan çykma näme

Kadadan çykma, programmanyň işleýşi wagtynda ýüze çykan käbir adatdan daşary, meýilleşdirilmedik ýagdaý. Java-da kadadan çykmalar köp bolup biler. Mysal üçin, bir faýldan tekst okaýan we konsola birinji setiri görkezýän kod ýazdyňyz.
public class Main {

   public static void main(String[] args) throws IOException {
       BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));
       String firstString = reader.readLine();
       System.out.println(firstString);
   }
}
Emma beýle faýl ýok! Programmanyň netijesi kadadan çykma bolar - FileNotFoundException. Netije:

Exception in thread "main" java.io.FileNotFoundException: C:\Users\Username\Desktop\test.txt (Системе не удается найти указанный путь)
Her bir kadadan çykma Java-da aýratyn synp bilen görkezilýär. Exceptionhli kadadan çykma synplary umumy “ata-babadan” - ene-atalar synpyndan gelýär Throwable. Kadadan çykma synpynyň ady, ýüze çykmagynyň sebäbini gysgaça görkezýär:
  • FileNotFoundException(faýl tapylmady)
  • ArithmeticException(matematika amalyny ýerine ýetireniňizde kadadan çykma)
  • ArrayIndexOutOfBoundsException(massiw öýjüginiň sany onuň uzynlygyndan has köp görkezilýär). Mysal üçin, 10 massiw massiw üçin konsolda öýjük massiwini [23] çykarjak bolsaňyz.
Java-da 400-e golaý şeýle synp bar! Näme üçin beýle köp? Programmistleriň olar bilen işlemegini has amatly etmek üçin. Göz öňüne getiriň: bir programma ýazdyňyz we işledilende şuňa meňzeş kadadan çykma bolýar:
Exception in thread "main"
Uh-uh: / Hiç zat düşnükli däl. Onuň haýsy ýalňyşlykdygy we nireden gelendigi belli däl. Peýdaly maglumat ýok. Suchöne şeýle dürli synplaryň kömegi bilen programmist özi üçin esasy zady - synpyň adyndaky ýalňyşlygyň görnüşini we ähtimal sebäbini alýar. Galyberse-de, konsolda görmek düýbünden başga zat:
Exception in thread "main" java.io.FileNotFoundException: C:\Users\Username\Desktop\test.txt (Системе не удается найти указанный путь)
Meseläniň näme bolup biljekdigi we meseläni çözmek üçin “haýsy tarapa gazmalydygy” derrew belli bolýar! Kadadan çykmalar, sapaklaryň islendik mysallary ýaly obýektlerdir.

Kadadan çykmalar we işlemek

Java-da kadadan çykmalar bilen işlemek üçin ýörite kod bloklary bar try: catchwe finally. Kadadan çykmalar: saklamak we gaýtadan işlemek - 2Programmistiň kadadan çykmalara garaşýan kody blokda ýerleşdirildi try. Bu, bu ýerde hökmany suratda kadadan çykma boljakdygyny aňlatmaýar. Diýmek, ol ýerde bolup biler we programmist muny bilýär. Aljak bolýan ýalňyşyňyzyň görnüşi blokda ýerleşdirilýär catch(“tutmak”). Şeýle hem, kadadan çykma ýüze çyksa ýerine ýetirilmeli ähli kodlar şu ýerde. Ine bir mysal:
public static void main(String[] args) throws IOException {
   try {
       BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));

       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (FileNotFoundException e) {

       System.out.println("Error! File not found!");
   }
}
Netije:

Ошибка! Файл не найден!
Kodumyzy iki blokda goýýarys. Birinji blokda “Faýl tapylmady” ýalňyşlygynyň ýüze çykmagyna garaşýarys. Bu blok try. Ikinjisinde, ýalňyşlyk ýüze çyksa näme etmelidigini programma aýdýarys. Mundan başga-da, belli bir ýalňyş görnüşi bar - FileNotFoundException. Blok ýaýlaryna başga bir kadadan çykma synpyny geçsek catch, tutulmaz.
public static void main(String[] args) throws IOException {
   try {
       BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));
       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (ArithmeticException e) {

       System.out.println("Error! File not found!");
   }
}
Netije:

Exception in thread "main" java.io.FileNotFoundException: C:\Users\Username\Desktop\test.txt (Системе не удается найти указанный путь)
Blokdaky kod catchişlemedi, sebäbi bu bloky saklamak üçin “sazladyk” ArithmeticExceptionwe blokdaky kod trybaşga bir görnüşi çykardy - FileNotFoundException. Munuň üçin skript ýazmadyk FileNotFoundException, şonuň üçin konsolda görkezilen programma deslapky görnüşde görkezilýär FileNotFoundException. Bu ýerde 3 zada üns bermeli. Ilki bilen. Synag blokundaky islendik kod setirinde kadadan çykma ýüze çykan badyna, kod mundan beýläk ýerine ýetirilmez. Programmanyň ýerine ýetirilmegi derrew blokda “bökjek” bolar catch. Mysal üçin:
public static void main(String[] args) {
   try {
       System.out.println("Divide a number by zero");
       System.out.println(366/0);//this line of code will throw an exception

       System.out.println("This");
       System.out.println("code");
       System.out.println("Not");
       System.out.println("will");
       System.out.println("done!");

   } catch (ArithmeticException e) {

       System.out.println("The program jumped to the catch block!");
       System.out.println("Error! You can't divide by zero!");
   }
}
Netije:

Делим число на ноль 
Программа перепрыгнула в блок catch! 
Ошибка! Нельзя делить на ноль! 
Ikinji setirdäki blokda try, sanlary 0-a bölmäge synanyşdyk, netijede kadadan çykma boldy ArithmeticException. Ondan soň blokuň 6-10 setirleri tryindi ýerine ýetirilmez. Aýdyşymyz ýaly, programma derrew bloky ýerine ýetirip başlady catch. Ikinjisi. Birnäçe blok bolup biler catch. Bir blokdaky kod trybir däl-de, birnäçe kadadan çykma zyňyp bilýän bolsa, olaryň her biri üçin öz blokuňyzy ýazyp bilersiňiz catch.
public static void main(String[] args) throws IOException {
   try {
       BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));

       System.out.println(366/0);
       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (FileNotFoundException e) {

       System.out.println("Error! File not found!");

   } catch (ArithmeticException e) {

       System.out.println("Error! Division by 0!");

   }
}
Bu mysalda iki blok ýazdyk catch. tryBlokda ýüze çyksa , FileNotFoundExceptionbirinji blok ýerine ýetiriler catch. Şeýle bolsa ArithmeticException, ikinjisi ýerine ýetiriler. Iň azyndan 50 blok ýazyp bilersiňiz catch., Öne, elbetde, 50 dürli ýalňyşlyk goýberip bilýän kod ýazmazlyk has gowudyr :) Üçünjisi. Koduňyzyň haýsy kadadan çykmalary taşlap biljekdigini nädip bilýärsiňiz? Elbetde, käbirleri hakda çaklap bilersiňiz, ýöne hemme zady kelläňizde saklamak mümkin däl. Şonuň üçin Java düzüjisi iň köp ýaýran kadadan çykmalary bilýär we haýsy ýagdaýlarda bolup biljekdigini bilýär. Mysal üçin, kod ýazan bolsaňyz we düzüjiniň işleýşinde 2 görnüşli kadadan çykma bolup biljekdigini bilýän bolsaňyz, koduňyz olary dolandyrýançaňyz düzülmez. Munuň mysallaryny aşakda göreris. Indi kadadan çykma meselesinde. Olary gaýtadan işlemegiň 2 usuly bar. Birinjisine eýýäm duşduk - bu usul kadadan çykmany özbaşdak çözüp biler catch(). Ikinji wariant bar - bu usul, çagyryş nokadyna kadadan çykma berip biler. Bu näme many berýär? Mysal üçin, synpymyzda printFirstString()bir faýly okaýan we konsola birinji setirini görkezýän usul bar - şol bir usul:
public static void printFirstString(String filePath) {

   BufferedReader reader = new BufferedReader(new FileReader(filePath));
   String firstString = reader.readLine();
   System.out.println(firstString);
}
Häzirki wagtda kodumyz düzülmeýär, sebäbi gözegçilik edilmedik kadadan çykmalar bar. 1-nji setirde faýla barýan ýoly görkezýärsiňiz. Düzediji şeýle koduň aňsatlyk bilen eltip biljekdigini bilýär FileNotFoundException. 3-nji setirde faýldan tekst okaýarsyňyz. IOExceptionBu amalda giriş-çykyş (Giriş-çykyş) wagtynda ýalňyşlyk ýüze çykyp biler . Indi düzüji size: “Dost, bu kadadan çykmalar ýüze çyksa näme etmelidigimi aýdýançaňyz, bu kody tassyklamaryn ýa-da düzmerin. Youazan koduňyza esaslanyp hökman bolup biler! ” . Gitjek ýeri ýok, ikisini gaýtadan işlemeli! Ilkinji gaýtadan işleýiş warianty eýýäm bize mälim: kodumyzy bir blokda ýerleşdirmeli trywe iki blok goşmaly catch:
public static void printFirstString(String filePath) {

   try {
       BufferedReader reader = new BufferedReader(new FileReader(filePath));
       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (FileNotFoundException e) {
       System.out.println("Error, file not found!");
       e.printStackTrace();
   } catch (IOException e) {
       System.out.println("Error while inputting/outputting data from file!");
       e.printStackTrace();
   }
}
Emma bu ýeke-täk mümkinçilik däl. Usulyň içindäki säwlik üçin skript ýazmakdan saklanyp bileris we kadadan çykmany ýokarsyna taşlap bileris. throwsBu usul deklarasiýasynda ýazylan açar söz bilen amala aşyrylýar :
public static void printFirstString(String filePath) throws FileNotFoundException, IOException {
   BufferedReader reader = new BufferedReader(new FileReader(filePath));
   String firstString = reader.readLine();
   System.out.println(firstString);
}
Sözden soň, throwsbu usulyň iş wagtynda taşlap biläýjek ähli kadadan çykmalaryny, dykgat bilen bölünýäris. Näme üçin beýle edilýär? Indi, programmada kimdir biri bu usula jaň etmek islese printFirstString(), özüni alyp barmagy kadadan çykarmaly bolar. Mysal üçin, programmanyň başga bir bölüminde kärdeşleriňizden biri siziň usulyňyzy çagyrýan usul ýazdy printFirstString():
public static void yourColleagueMethod() {

   //...your colleague's method does something

   //...and at one moment calls your printFirstString() method with the file it needs
   printFirstString("C:\\Users\\Eugene\\Desktop\\testFile.txt");
}
Roralňyşlyk, kod düzenok! Usulda printFirstString()ýalňyşlyk bilen skript ýazmadyk . Şonuň üçin wezipe bu usuly ulanjaklaryň egnine düşýär. .Agny, bu usul yourColleagueMethod()indi birmeňzeş 2 wariant bilen ýüzbe-ýüz bolýar: ýa-da ulanylanda “gelýän” iki kadadan çykmany try-catchýa-da hasam öňe sürmeli.
public static void yourColleagueMethod() throws FileNotFoundException, IOException {
   //...the method does something

   //...and at one moment calls your printFirstString() method with the file it needs
   printFirstString("C:\\Users\\Eugene\\Desktop\\testFile.txt");
}
Ikinji ýagdaýda, gaýtadan işlemek indiki usulyň egnine düşer - jaň eder yourColleagueMethod(). Şonuň üçin şeýle mehanizm “kadadan çykmany ýokaryk zyňmak” ýa-da “ýokarsyna geçmek” diýilýär. Kadadan çykmalary ulanyp throws, kod düzýär. Häzirki wagtda düzüji: “Bolýar, bolýar. Koduňyzda bir topar potensial kadadan çykmalar bar, ýöne her niçigem bolsa düzerin. Bu söhbetdeşlige gaýdyp geleris! " Programmanyň haýsydyr bir ýerinde kadadan çykmalary ulanmadyk bir usula jaň edeniňizde, düzüji beren wadasyny ýerine ýetirýär we size ýene-de ýatladýar. Ahyrynda, blok hakda gürleşeris finally(jezany bagyşlaň). Bu, triumvirate garşy kadadan çykmagyň soňky bölegi try-catch-finally. Onuň aýratynlygy, islendik programma amaly ssenariýasynda ýerine ýetirilmegi.
public static void main(String[] args) throws IOException {
   try {
       BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));

       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (FileNotFoundException e) {
       System.out.println("Error! File not found!");
       e.printStackTrace();
   } finally {
       System.out.println("And here is the finally block!");
   }
}
Bu mysalda blokyň içindäki kod finallyiki ýagdaýda-da ýerine ýetirilýär. Blokdaky kod trydoly ýerine ýetirilen bolsa we kadadan çykma bolmasa, blok ahyrynda ot alar finally. Içindäki kod trykesilse we programma blokda bökse catch, içindäki kod ýerine ýetirilenden soň catch, blok henizem saýlanar finally. Näme üçin zerur? Esasy maksady koduň zerur bölegini ýerine ýetirmek; ýagdaýlara garamazdan tamamlanmaly bölegi. Mysal üçin, köplenç programma tarapyndan ulanylýan käbir çeşmeleri boşadýar. Kodumyzda, bir faýldan maglumatlary okamak we ony a-a geçirmek üçin akym açýarys BufferedReader. Biziňkiler readerýapylmaly we çeşmeler boşadylmaly. Bu islendik ýagdaýda edilmelidir: programmanyň garaşylşy ýaly işlemegi ýa-da kadadan çykma ähmiýeti ýok. Muny bir blokda etmek amatly finally:
public static void main(String[] args) throws IOException {

   BufferedReader reader = null;
   try {
       reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));

       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (FileNotFoundException e) {
       e.printStackTrace();
   } finally {
       System.out.println("And here is the finally block!");
       if (reader != null) {
           reader.close();
       }
   }
}
Indi, programma işleýän wagtynda nämeleriň bolup geçýändigine garamazdan, basyp alnan çeşmeler barada alada edendigimize doly ynanýarys :) Bu kadadan çykmalar hakda bilmeli zatlaryňyz däl. Roralňyşlyk bilen işlemek programmirlemekde gaty möhüm mowzuk: birden köp makala oňa bagyşlanýar. Indiki sapakda kadadan çykmalaryň haýsy görnüşleriniň bardygyny we öz kadadan çykmaňyzy nädip döretmelidigini öwreneris :) Şol ýerde görüşeris!
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION