JavaRush /Java блогу /Random-KY /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 тorнде өзүнчө класс менен көрсөтүлөт. Бардык өзгөчө класстар жалпы "ата-бабадан" - ата-эне класстан келет Throwable. Өзгөчө класстын аталышы, адатта, анын пайда болушунун себебин кыскача чагылдырат:
  • FileNotFoundException(Файл табылган жок)
  • ArithmeticException(математикалык операцияны аткарууда өзгөчө)
  • ArrayIndexOutOfBoundsException(массивдин уячасынын саны анын узундугунан ашып көрсөтүлөт). Мисалы, 10 узундуктагы массив үчүн уяча массивинин [23] консолуна чыгарууга аракет кылсаңыз.
Java тorнде 400дөй класс бар! Эмне үчүн мынча көп? Тактап айтканда, алар менен иштөө программисттер үчүн ыңгайлуураак кылуу үчүн. Элестетиңиз: сиз программа жаздыңыз жана ал иштегенде, ал төмөнкүдөй өзгөчөлүктү жаратат:
Exception in thread "main"
Ух-ух :/ Эч нерсе так эмес. Бул кандай ката экени жана кайдан чыкканы белгисиз. Пайдалуу маалымат жок. Бирок класстардын мындай ар түрдүүлүгүнүн аркасында программист өзү үчүн эң негизги нерсени – класстын аталышында камтылган катанын түрүн жана анын ыктымал себебин алат. Кантсе да, консолдо көрүү таптакыр башка нерсе:
Exception in thread "main" java.io.FileNotFoundException: C:\Users\Username\Desktop\test.txt (Системе не удается найти указанный путь)
Маселе эмнеде болушу мүмкүн жана маселени чечүү үчүн "кайсы багытта казуу керек" дароо айкын болот! Класстардын бардык инстанциялары сыяктуу эле, өзгөчөлүктөр an object болуп саналат.

Тутуу жана иштетүү өзгөчө учурлар

Java'да өзгөчөлүктөр менен иштөө үчүн атайын code блоктору бар: try, catchжана finally. Өзгөчө жагдайлар: кармоо жана кайра иштетүү - 2Программист өзгөчө кырдаалдардын болушун күткөн code блокко жайгаштырылат try. Бул бул жерде сөзсүз түрдө өзгөчөлүк болот дегенди билдирбейт. Бул ошол жерде болушу мүмкүн дегенди билдирет жана программист муну билет. Сиз күткөн катанын түрү блокко catch(«кармап алуу») жайгаштырылат. Бул жерде, эгерде өзгөчө жагдай пайда болсо, аткарылышы керек болгон бардык codeдор жайгаштырылат. Бул жерде бир мисал:
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!");
   }
}
Жыйынтык:

Ошибка! Файл не найден!
Биз codeубузду эки блокко койдук. Биринчи блокто биз "Файл табылган жок" катасы пайда болушу мүмкүн деп күтөбүз. Бул блок try. Экинчисинде биз программага ката кетсе эмне кылуу керектигин айтабыз. Мындан тышкары, ката белгилүү бир түрү бар - FileNotFoundException. Эгерде биз catchдагы бир өзгөчө классты блоктук кашааларга өткөрсөк, ал кармалbyte.
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 (Системе не удается найти указанный путь)
Блоктогу code 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мындан ары аткарылbyte. Биз айткандай, программа дароо блокту ишке ашыра баштады 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, албетте, 50 түрдүү каталарды ыргыта турган codeду жазбаганыңыз жакшы :) Үчүнчүсү. Кодуңуз кандай өзгөчөлүктөргө алып келиши мүмкүн экенин кайдан билесиз? Ооба, сиз, албетте, кээ бирлери жөнүндө божомолдоого болот, бирок баарын башыңызда сактоо мүмкүн эмес. Ошондуктан, Java компилятору эң кеңири таралган өзгөчөлүктөр жөнүндө билет жана алар кандай кырдаалдарда болушу мүмкүн экенин билет. Мисалы, эгер сиз code жазсаңыз жана компилятор анын иштеши учурунда өзгөчө жагдайлардын 2 түрү болушу мүмкүн экенин билсе, сиз аларды иштетмейинче сиздин codeуңуз компиляцияланbyte. Төмөндө мунун мисалдарын көрөбүз. Азыр өзгөчөлүктөр менен иштөө жөнүндө. Аларды иштетүүнүн 2 жолу бар. Биз биринчисин жолуктурдук - ыкма блокто өзгөчө кырдаалды өз алдынча чече алат catch(). Экинчи вариант бар - ыкма чалуу стекинен өзгөчөлүктү ыргыта алат. Бул эмнени билдирет? printFirstString()Мисалы, биздин класста файлды окуй турган жана анын биринчи сабын консолго көрсөтө турган ыкма бар :
public static void printFirstString(String filePath) {

   BufferedReader reader = new BufferedReader(new FileReader(filePath));
   String firstString = reader.readLine();
   System.out.println(firstString);
}
Учурда биздин code компиляцияланbyte, анткени анда иштетилбеген өзгөчөлүктөр бар. 1-сапта сиз файлдын жолун көрсөтөсүз. Компилятор мындай code оңой алып келиши мүмкүн экенин билет FileNotFoundException. 3-сапта сиз файлдан текстти окуйсуз. IOExceptionБул процессте киргизүү-чыгаруу (Киргизүү-Чыгуу) учурунда ката оңой эле пайда болушу мүмкүн . Эми компилятор сизге айтып жатат: “Улуу, мен бул codeду бекитпейм же ушул өзгөчөлүктөрдүн бири болуп калса, эмне кылышым керектигин айтмайынча, аны түзбөйм. Жана алар сиз жазган 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();
   }
}
Бирок бул жалгыз вариант эмес. Методдун ичиндеги ката үчүн скрипт жазуудан кача алабыз жана жөн гана өзгөчөлүктү жогоруга ыргыта алабыз. 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 түзүлөт. Ушул учурда компилятор: «Макул, макул. Сиздин 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 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();
       }
   }
}
Эми биз программа иштеп жатканда эмне болуп жатканына карабастан, ээлеген ресурстарга кам көргөнүбүзгө толук ишенебиз :) Бул өзгөчө учурлар жөнүндө бorшиңиз керек болгон нерсе эмес. Ката менен иштөө программалоодо абдан маанилүү тема: ага бирден ашык макала арналган. Кийинки сабакта биз бөтөнчөлүктөрдүн кандай түрлөрү бар экенин жана өзүңүздүн өзгөчөлүгүңүздү кантип түзүүнү үйрөнөбүз :) Көрүшкөнчө!
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION