Салом! Дар лексияи гузашта мо бо чунин як ҷанбаи забони Java ҳамчун истисно шинос шудем ва мисолҳои кор бо онҳо дидем. Имрӯз мо сохтори онҳоро амиқтар дида мебароем ва инчунин тарзи навиштани истисноҳои худро меомӯзем :)
Намудҳои истисноҳо
Тавре ки мо гуфтем, дар Java дарсҳои истисноӣ хеле зиёданд, тақрибан 400! Аммо ҳамаи онҳо ба гурӯҳҳо тақсим шудаанд, бинобар ин онҳоро дар хотир нигоҳ доштан хеле осон аст. Ин чунин аст: Ҳама истисноҳо синфи аҷдоди умумӣ дорандThrowable
. Аз он ду гурӯҳи калон пайдо мешаванд - истисноҳо (истисно) ва хатоҳо (Хато). Хатогӣ хатои муҳим дар ҷараёни иҷрои барнома мебошад, ки бо кори мошини виртуалии Java алоқаманд аст. Дар аксари ҳолатҳо, Хатогиро коркард кардан лозим нест, зеро он баъзе камбудиҳои ҷиддии codeро нишон медиҳад. Хатогиҳои машҳур: StackOverflowError
- масалан, вақте ки метод беохир худашро даъват мекунад ва OutOfMemoryError
- вақте рух медиҳад, ки хотира барои эҷоди an objectҳои нав кофӣ нест. Тавре ки шумо мебинед, дар ин ҳолатҳо, аксар вақт ягон чизи махсусе барои коркард вуҷуд надорад - code танҳо нодуруст навишта шудааст ва онро дубора ислоҳ кардан лозим аст. Истисноҳо , воқеан, истисноҳо мебошанд: ҳолати истисноӣ ва ғайринақшанашуда, ки ҳангоми иҷрои барнома рух дод. Инҳо хатогиҳои ҷиддӣ нестанд, аммо онҳо диққати моро талаб мекунанд. Ҳама истисноҳо ба 2 намуд тақсим мешаванд - санҷидашуда ( санҷидашуда ) ва бетаҷҳизшуда ( бетараф ). Ҳама истисноҳои тафтишшуда аз Exception
. "Тасдиқшаванда" чӣ маъно дорад? Мо дар ин бора қисман дар лексияи охирин зикр кардем : "...компилятори Java дар бораи истисноҳои маъмултарин медонад ва медонад, ки онҳо дар кадом ҳолатҳо рух дода метавонанд." Масалан, ӯ медонад, ки агар барномасоз маълумотро аз файл дар code хонад, вазъият ба осонӣ ба вуҷуд омада метавонад, ки файл вуҷуд надорад. Ва ин гуна ҳолатҳое зиёданд, ки ӯ пешакӣ пешгӯӣ карда метавонад. Аз ин рӯ, компилятор рамзи моро пешакӣ барои истисноҳои эҳтимолӣ тафтиш мекунад. Агар он онҳоро пайдо кунад, он codeро тартиб намедиҳад, то даме ки мо онҳоро коркард кунем ё ба боло интиқол диҳем. Навъи дуюми истисно "бесанҷида" аст. Онҳо аз синф меоянд RuntimeException
. Чӣ тавр онҳо аз озмоишшудагон фарқ мекунанд? Чунин ба назар мерасад, ки инчунин як қатор синфҳои гуногун мавҷуданд, ки аз RuntimeException
истисноҳои мушаххаси вақти корӣ омадаанд ва тавсиф мекунанд. Фарқият дар он аст, ки компилятор ин хатогиҳоро интизор нест. Вай ба назар чунин менамояд: «Хангоми навиштани code ман ягон чизи шубханокро наёфтам, вале дар вакти кор ягон чиз нодуруст руй дод. Аз афташ дар code хатогихо мавчуданд!». Ва воқеан ҳам ҳаст. Истисноҳои тафтишнашуда аксар вақт натиҷаи хатогиҳои барномасоз мебошанд. Ва компилятор ба таври возеҳ қодир нест, ки ҳама ҳолатҳои нодурусти имконпазирро, ки одамон метавонанд бо дасти худ эҷод кунанд, таъмин кунад :) Аз ин рӯ, он коркарди чунин истисноҳоро дар codeекси мо тафтиш намекунад. Шумо аллакай бо якчанд истисноҳои тафтишнашуда дучор шудаед:
ArithmeticException
ҳангоми ба сифр тақсим кардан ба амал меоядArrayIndexOutOfBoundsException
Ҳангоми кӯшиши дастрасӣ ба ячейкаи берун аз массив рух медиҳад.
Чӣ тавр партофтан истиснои худро
Албатта, созандагони Java наметавонанд ҳама ҳолатҳои истисноиро, ки дар барномаҳо ба вуҷуд меоянд, таъмин кунанд. Дар ҷаҳон барномаҳо хеле зиёданд ва онҳо хеле гуногунанд. Аммо ин хуб аст, зеро агар лозим бошад, шумо метавонед истисноҳои худро эҷод кунед. Ин хеле осон анҷом дода мешавад. Шумо бояд танҳо як синфи шахсии худро эҷод кунед. Номи он бояд бо "истисно" хотима ёбад. Компилятор ба ин ниёз надорад, аммо барномасозоне, ки codeи шуморо мехонанд, фавран мефаҳманд, ки ин як синфи истисно аст. Илова бар ин, шумо бояд нишон диҳед, ки синф аз синф меоядException
. Ин аллакай барои компилятор ва кори дуруст зарур аст. Масалан, мо як синфи Dog дорем - Dog
. Мо метавонем сагро бо истифода аз walk()
. Аммо пеш аз ин, мо бояд тафтиш кунем, ки саги мо гулӯла, ришта ва даҳон дорад. Агар яке аз инҳо набошад, мо истиснои худро мепартоем DogIsNotReadyException
. Рамзи он чунин хоҳад буд:
public class DogIsNotReadyException extends Exception {
public DogIsNotReadyException(String message) {
super(message);
}
}
Барои нишон додани он, ки синф истисно аст, шумо бояд пас аз номи синф Exception-ро нависед : ин маънои онро дорад, ки "синф аз истиснои синф бармеояд." Дар конструктор мо танҳо конструктори синфро Exception
бо сатр даъват мекунем message
- он ба корбар паёми системаро нишон медиҳад, ки хатогиро тавсиф мекунад. Ин дар codeи синфии мо чунин хоҳад буд:
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!");
}
}
}
Акнун усули мо walk()
истисноро мегузорад DogIsNotReadyException
. Ин бо истифода аз калимаи калидӣ анҷом дода мешавад throw
. Тавре ки мо қаблан гуфта будем, истисно an object аст. Аз ин рӯ, дар усули мо, вақте ки вазъияти истисноӣ рух медиҳад - дар саг чизе намерасад - мо an objectи нави синфӣ эҷод мекунем DogIsNotReadyException
ва онро бо истифода аз калимаи throw
. walk()
Мо ба имзои метод партовҳо илова мекунем DogIsNotReadyException
. Ба ибораи дигар, компилятор ҳоло медонад, ки занги метод walk()
метавонад ба истисно оварда расонад. Ҳамин тавр, вақте ки мо инро дар ҷое дар барнома даъват мекунем, истисноро бояд ҳал кард. Биёед кӯшиш кунем, ки ин корро бо усули main()
:
public static void main(String[] args) {
Dog dog = new Dog("Mukhtar");
dog.putCollar();
dog.putMuzzle();
dog.walk();//Unhandled exception: DogIsNotReadyException
}
Тартиб намедиҳад, истисно коркард намешавад! Биёед codeи худро дар блок печонем try-catch
, то истисноро ҳал кунем:
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);
}
}
Акнун биёед баромади консолро бубинем:
Ошейник надет!
Намордник надет!
Собираемся на прогулку!
Собака Мухтар не готова к прогулке! Проверьте экипировку!
Проверяем снаряжение! Ошейник надет? true
Поводок надет? false
Намордник надет? true
Бубинед, ки баромади консол то чӣ андоза иттилоотӣ бештар шудааст! Мо хар як кадамеро, ки дар программа руй дод, мебинем; Мо мебинем, ки хато дар куҷо рух додааст ва фавран пай мебарем, ки саги мо чӣ намерасад :) Ҳамин тавр мо истисноҳои худро эҷод мекунем. Тавре ки шумо мебинед, ҳеҷ чиз мураккаб нест. Ва гарчанде ки таҳиягарони Java барои сагонҳои нодуруст муҷаҳҳазшуда ба забони худ истиснои махсус илова накарданд, мо назорати онҳоро ислоҳ кардем :)
GO TO FULL VERSION