JavaRush /Блоги Java /Random-TG /Истисноҳо дар Java: сайд ва коркард

Истисноҳо дар Java: сайд ва коркард

Дар гурӯҳ нашр шудааст
Салом! Ман аз шикастани он нафрат дорам, аммо қисми зиёди кори барномасоз бо хатогиҳо сарукор дорад. Ва аксар вақт - бо худ. Чунин мешавад, ки одамоне нест, ки хато накунанд. Ва ин гуна барномаҳо низ вуҷуд надоранд. Албатта, чизи асосӣ ҳангоми кор бо хатогӣ фаҳмидани сабаби он аст. Ва дар барнома метавонад як қатор сабабҳо вуҷуд дошта бошанд. Дар як лаҳза, созандагони Java бо саволе рӯбарӯ шуданд: бо ин хатогиҳои эҳтимолии барномаҳо чӣ бояд кард? Пешгирӣ аз онҳо комилан ғайривоқеист. Барномасозон метавонанд чизе бинависанд, ки ҳатто тасаввур кардан ғайриимкон аст :) Ин маънои онро дорад, ки дар забон механизми мубориза бо хатогиҳо бунёд кардан лозим аст. Ба ибораи дигар, агар дар барнома ягон хатогӣ рух дода бошад, барои кори минбаъда скрипт лозим аст. Ҳангоми рух додани хато барнома бояд маҳз чӣ кор кунад? Имруз мо бо ин механизм шинос мешавем. Ва он "истисноҳо " номида мешавад .

Дар Java чӣ истисно аст

Истисно ин баъзе ҳолатҳои истисноӣ ва ғайринақшавӣ мебошад, ки дар ҷараёни кори барнома рух додааст. Дар Java метавон мисолҳои зиёди истисноҳо вуҷуд дорад. Масалан, шумо codeеро навиштед, ки матнро аз файл мехонад ва сатри аввалро ба консол намоиш медиҳад.
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);
   }
}
Аммо чунин файл вуҷуд надорад! Натиҷаи барнома истисно хоҳад буд - FileNotFoundException. Хулоса:

Exception in thread "main" java.io.FileNotFoundException: C:\Users\Username\Desktop\test.txt (Системе не удается найти указанный путь)
Ҳар як истисно бо синфи алоҳида дар Java муаррифӣ мешавад. Ҳама синфҳои истисноӣ аз як "аҷдод" - синфи волидайн бармеоянд Throwable. Номи синфи истисно одатан сабаби пайдоиши онро ба таври мухтасар инъикос мекунад:
  • FileNotFoundException(парванда дарёфт нашуд)
  • ArithmeticException(истисно ҳангоми иҷрои амалиёти математикӣ)
  • ArrayIndexOutOfBoundsException(рақами ячейкаи массив аз дарозии он зиёдтар аст). Масалан, агар шумо кӯшиш кунед, ки массиви ячейка[23]-ро ба консол барои массиви дарозии 10 баровардан кунед.
Дар Java тақрибан 400 чунин синфҳо мавҷуданд! Чаро ин қадар зиёд? Махз барои он ки барои барномасозон кор бо онхо кулайтар шавад. Тасаввур кунед: шумо барнома навиштед ва вақте ки он кор мекунад, он истисноеро мегузорад, ки чунин менамояд:
Exception in thread "main"
Uh-uh :/ Ҳеҷ чиз равшан нест. Ин чӣ гуна хато аст ва аз куҷо пайдо шудааст, маълум нест. Маълумоти муфид нест. Аммо ба шарофати чунин синфҳои гуногун, барномасоз чизи асосиро барои худ мегирад - намуди хато ва сабаби эҳтимолии он, ки дар номи синф мавҷуд аст. Дар ниҳоят, дар консол дидан чизи тамоман дигар аст:
Exception in thread "main" java.io.FileNotFoundException: C:\Users\Username\Desktop\test.txt (Системе не удается найти указанный путь)
Дарҳол маълум мешавад, ки мушкилот чӣ гуна буда метавонад ва "дар кадом самт кофтан" барои ҳалли мушкилот! Истисноҳо, ба монанди ҳама гуна мисолҳои синфҳо, an objectҳо мебошанд.

Истисноҳои сайд ва коркард

Барои кор бо истисноҳо дар Java, блокҳои махсуси рамзӣ мавҷуданд: try, catchва finally. Истисноҳо: боздошт ва коркард - 2Рамде, ки дар он барномасоз интизори рӯй додани истисноҳоро интизор аст, дар блок ҷойгир карда мешавад try. Ин маънои онро надорад, ки дар ин макон истисно ҳатман рӯй медиҳад. Ин маънои онро дорад, ки он метавонад дар он ҷо рӯй диҳад ва барномасоз аз он огоҳ аст. Навъи хатогие, ки шумо интизор ҳастед, дар блок ҷойгир карда мешавад catch("сайд"). Дар ин ҷо инчунин ҳамаи рамзҳое ҷойгир карда мешаванд, ки ҳангоми рух додани истисно бояд иҷро карда шаванд. Инак як мисол:
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!");
   }
}
Хулоса:

Ошибка! Файл не найден!
Мо рамзи худро дар ду блок ҷойгир мекунем. Дар блоки аввал мо интизорем, ки хатогии "Файл ёфт нашуд" метавонад рух диҳад. Ин блок аст try. Дар дуюм, мо ба барнома мегӯем, ки агар хатогӣ рух диҳад, чӣ бояд кард. Гузашта аз ин, як навъи мушаххаси хато вуҷуд дорад - FileNotFoundException. Агар мо catchсинфи истисноии дигарро ба қавсҳои блок гузаронем, он дастгир карда намешавад.
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!");
   }
}
Хулоса:

Exception in thread "main" java.io.FileNotFoundException: C:\Users\Username\Desktop\test.txt (Системе не удается найти указанный путь)
Рамзи блок catchкор накард, зеро мо ин блокро барои боздоштан “конфигуратсия кардем” ArithmeticExceptionва codeи блок tryнавъи дигарро хориҷ кард - FileNotFoundException. Мо барои скрипт нанавиштем FileNotFoundException, бинобар ин барнома дар консол маълумотеро намоиш медиҳад, ки бо нобаёнӣ барои FileNotFoundException. Дар ин ҷо шумо бояд ба 3 чиз диққат диҳед. Аввал. Ҳамин ки дар ягон сатри code дар блоки озмоишӣ истисно рух медиҳад, codeи баъд аз он дигар иҷро намешавад. Иҷрои барнома фавран ба блок "ҷаҳида" мешавад catch. Барои намуна:
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!");
   }
}
Хулоса:

Делим число на ноль 
Программа перепрыгнула в блок catch! 
Ошибка! Нельзя делить на ноль! 
Дар блоки tryсатри дуюм мо кӯшиш кардем, ки ададро ба 0 тақсим кунем, ки дар натиҷа истисно шуд ArithmeticException. Баъд аз ин, сатрҳои 6-10 блок tryдигар иҷро намешаванд. Тавре ки мо гуфтем, барнома фавран ба иҷрои блок оғоз кард catch. Дуюм. Якчанд блокҳо вуҷуд дошта метавонанд catch. Агар code дар блок tryметавонад на як, балки якчанд намуди истисноҳоро партояд, шумо метавонед барои ҳар яки онҳо блоки худро нависед 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!");

   }
}
Дар ин мисол мо ду блок навиштем catch. Агар , дар блок tryрух диҳад FileNotFoundException, блоки аввал иҷро карда мешавад catch. Агар рӯй диҳад ArithmeticException, дуюмаш иҷро карда мешавад. Шумо метавонед ҳадди аққал 50 блок нависед.Аммо catch, албатта, беҳтар аст, ки codeеро нанависед, ки метавонад 50 намуди хатогиҳоро партояд :) Сеюм. Шумо аз куҷо медонед, ки codeи шумо кадом истисноҳоро ба вуҷуд оварда метавонад? Хуб, шумо метавонед, албатта, дар бораи баъзеҳо тахмин кунед, аммо ҳама чизро дар сари худ нигоҳ доштан ғайриимкон аст. Аз ин рӯ, компилятори Java дар бораи истисноҳои маъмултарин медонад ва медонад, ки онҳо дар кадом ҳолатҳо рух дода метавонанд. Масалан, агар шумо code навиштед ва компилятор донад, ки дар давоми кори он 2 намуди истисноҳо рух дода метавонанд, codeи шумо то даме ки шумо онҳоро идора мекунед, тартиб намедиҳад. Мо дар зер мисолҳои инро мебинем. Ҳоло дар бораи коркарди истисно. 2 роҳи коркарди онҳо вуҷуд дорад. Мо аллакай бо аввалин вохӯрдем - усул метавонад истисноро дар блок мустақилона ҳал кунад catch(). Варианти дуюм вуҷуд дорад - усул метавонад истисноро дар стеки зангҳо боло барад. Ин чӣ маъно дорад? Масалан, дар синфи мо мо методе дорем - ҳамон як printFirstString()- ки файлро мехонад ва сатри аввалашро дар консол намоиш медиҳад:
public static void printFirstString(String filePath) {

   BufferedReader reader = new BufferedReader(new FileReader(filePath));
   String firstString = reader.readLine();
   System.out.println(firstString);
}
Дар айни замон рамзи мо тартиб намедиҳад, зеро он истисноҳои коркарднашаванда дорад. Дар сатри 1 шумо роҳи файлро нишон медиҳед. Компилятор медонад, ки чунин code метавонад ба осонӣ ба FileNotFoundException. Дар сатри 3 шумо матнро аз файл мехонед. IOExceptionДар ин раванд хатогӣ ҳангоми вуруд-баромад (Ворид-Баромад) метавонад ба осонӣ рух диҳад . Ҳоло компилятор ба шумо мегӯяд: "Дӯстам, ман ин codeро тасдиқ намекунам ва онро тартиб намедиҳам, то даме ки шумо ба ман нагӯед, ки агар яке аз ин истисноҳо рух диҳад, ман бояд чӣ кор кунам. Ва онҳо бешубҳа метавонанд дар асоси codeи навиштаи шумо рӯй диҳанд! ” . Ҷои рафтан нест, шумо бояд ҳардуро коркард кунед! Варианти коркарди аввал ба мо аллакай шинос аст: мо бояд рамзи худро дар блок ҷойгир кунем tryва ду блок илова кунем 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();
   }
}
Аммо ин ягона вариант нест. Мо метавонем аз навиштани скрипт барои хато дар дохor усул худдорӣ кунем ва танҳо истисноро ба боло партоем. Ин бо истифода аз калимаи калидӣ анҷом дода мешавад throws, ки дар эъломияи метод навишта шудааст:
public static void printFirstString(String filePath) throws FileNotFoundException, IOException {
   BufferedReader reader = new BufferedReader(new FileReader(filePath));
   String firstString = reader.readLine();
   System.out.println(firstString);
}
Пас аз калима, throwsмо ҳама намуди истисноҳоро бо вергул ҷудо карда номбар мекунем, ки ин усул метавонад ҳангоми амалиёт партофта шавад. Чаро ин кор карда мешавад? Ҳоло, агар касе дар барнома мехоҳад методро даъват кунад printFirstString(), ӯ бояд худаш коркарди истисноро амалӣ кунад. Масалан, дар қисми дигари барнома, яке аз ҳамкорони шумо усуле навишт, ки дар доираи он усули шумо номида мешавад 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");
}
Хатогӣ, code тартиб дода намешавад! Мо дар усул printFirstString()скрипти коркарди хатогиро нанавиштем . Бинобар ин вазифа ба души онхое меафтад, ки ин усулро ба кор мебаранд. Яъне, усул yourColleagueMethod()ҳоло бо ҳамон 2 вариант рӯбарӯ аст: он бояд ё ҳарду истисноҳоеро, ки бо истифода аз "парвоз" ба он "парвоз" кардаанд try-catch, коркард кунад ё онҳоро ба оянда интиқол диҳад.
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");
}
Дар ҳолати дуюм, коркард ба дӯши усули навбатӣ оид ба стек меафтад - яке, ки занг хоҳад зад yourColleagueMethod(). Аз ин рӯ, чунин механизмро "ба боло партофтани истисно" ё "ба боло гузаштан" меноманд. Вақте ки шумо бо истифода аз истисноҳо мепартоед throws, code тартиб медиҳад. Дар ин лахза мураттиб гуё мегуяд: «Хуб, хуб. Рамзи шумо як қатор истисноҳои эҳтимолиро дар бар мегирад, аммо ман онро ба ҳар ҳол тартиб медиҳам. Мо ба ин сӯҳбат бармегардем! ” Ва ҳангоме ки шумо ба ягон усули барнома занг мезанед, ки истисноҳои онро ҳал накардааст, компилятор ваъдаи худро иҷро мекунад ва бори дигар ба шумо дар бораи онҳо хотиррасон мекунад. Ниҳоят, мо дар бораи блок гап мезанем finally(бахшиш кунед). Ин қисми охирини коркарди истисноии триумвират аст try-catch-finally. Хусусияти он дар он аст, ки он дар ҳама гуна сенарияи амалиёти барнома иҷро карда мешавад.
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!");
   }
}
Дар ин мисол, codeи дохor блок finallyдар ҳарду ҳолат иҷро карда мешавад. Агар code дар блок tryпурра иҷро шуда бошад ва истисно накунад, блок дар охир оташ мегирад finally. Агар codeи дарун tryқатъ шуда бошад ва барнома ба блок ҷаҳида шавад catch, пас аз иҷро шудани codeи дарунӣ catch, блок ҳамчунон интихоб карда мешавад finally. Чаро он лозим аст? Мақсади асосии он иҷрои қисми зарурии code мебошад; он қисме, ки новобаста аз вазъият бояд анҷом дода шавад. Масалан, он аксар вақт баъзе захираҳоеро, ки барнома истифода мебарад, озод мекунад. Дар codeи худ мо ҷараёнро кушоем, то маълумотро аз файл хонем ва онро ба BufferedReader. Мо readerбояд баста шавад ва захираҳо озод карда шаванд. Ин бояд дар ҳар сурат анҷом дода шавад: муҳим нест, ки барнома мувофиқи интизорӣ кор мекунад ё истисно мегузорад. Ин корро дар блок қулай аст 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();
       }
   }
}
Ҳоло мо комилан мутмаин ҳастем, ки мо дар бораи захираҳои ишғолшуда ғамхорӣ кардем, новобаста аз он, ки ҳангоми иҷро кардани барнома чӣ рӯй медиҳад :) Ин ҳама чизе нест, ки шумо дар бораи истисноҳо донед. Муносибати хатогиҳо як мавзӯи хеле муҳим дар барномасозӣ аст: зиёда аз як мақола ба он бахшида шудааст. Дар дарси оянда мо мефаҳмем, ки чӣ гуна истисноҳо вуҷуд доранд ва чӣ гуна истиснои худро эҷод кардан мумкин аст :) Дар он ҷо вомехӯрем!
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION