[သင္ခန္းစာ ၁၄] Handle exception
ဒီ သင္ခန္းစာမွာေတာ့ exception handling အေၾကာင္းကို မိတ္ဆက္ေပးသြားမွာျဖစ္ပါတယ္။
Precondition ေတြကေတာ့multiple classes ေတြကိုအသံုးျပဳထားတဲ့ exercises ရွိရမယ္။
(တကယ္လို ့ mulyiple classes ကိုသံုးျပီး exercise လုပ္တာကို မမွတ္မိေတာ့ရင္ သင္ခန္းစာ 10 ရဲ့ Deal with multiple classကိုမွာျပန္ေလ့လာနိုင္ပါတယ္)
“Exception” ဆိုတာဘာလဲ?
Exception ဆိုတာ JAVA programming နဲ ့ဘယ္လိုဆက္စပ္တယ္ဆိုတာကို သိလာ:?
Computer မွာအလုပ္အမ်ားစုကို “input”,”process” and “output”ဆိုတဲ့ အလုပ္ေတြနဲ ့ဖြဲ ့စည္းထားတယ္ဆိုတာ အရင္ျပီးခဲ့တဲ့ သင္ခန္းစာေတြမွာ အမ်ားၾကီးေလ့လာျပီးပါျပီ။
ဥပမာအားျဖင့္ 65,536/4,096 ဆိုတဲ့ division processကိုတြက္ၾကည့္ရေအာင္။
ဒီ division ပုစၦာမွာဆိုရင္ “input”,”process” နွင့္ “output” ေတြကိုေအာက္မွာရွင္းျပထားပါတယ္။
Input : 65536 and 4096(calculation လုပ္ဖို ့အတြက္ values ေတြလိုအပ္ပါတယ္)
Processing: Division.
Output: 16 (16 ကcalculation ရဲ့အေျဖျဖစ္ပါတယ္).
Computer ရဲ့အဆင္ေျပတဲ့အခ်က္ကေတာ့ user က input ကိုုေျပာင္းျခင္းအားျဖင့္ အေျဖကိုအခ်ိန္တိုတိုအတြင္းမွာ ရရွိနိုင္ပါတယ္။
Processing ျပဳလုပ္တဲ့ အပိုင္းကၾကည့္မယ္ဆိုရင္ user ရဲ့ input ေတြက အမ်ိဳးမ်ိဳးျဖစ္နိုင္ပါတယ္။ ဥပမာ
123/0 (zero နဲ ့စားလို ့မရပါဘူး)
456/ abc (input ကကိန္းဂဏန္း မဟုတ္ဘဲ character ျဖစ္ေနပါတယ္)
ကဲ မင္းဘာလုပ္မလဲ? အခုေနရာကစျပီး program ကိုဘယ္လိုေရးရမလဲဆိုတာ စဥ္းစားၾကည့္ရေအာင္။
ပထမဆံုးအေနနဲ ့ သင္ခန္းစာ အစမွာရွင္းျပခဲ့တဲ့ division ဥပမာကိုသံုးျပီး program တစ္ပုဒ္ေရးၾကရေအာင္။
“input”ဆိုတာ argument တစ္ခု “processing” ဆိုတာ method ျဖစ္ျပီး “output” ဆိုတာ method ရဲ့ return value နဲ ့တူညီတယ္ဆိုတာကို နားလည္တယ္လို ့ထင္ပါတယ္။
အရိုးရွင္းဆံုးအေနနဲ ့ေျပာရရင္ division program ရဲ့ argument နွင့္ return value ဧ။္type ကို interger (int type) လို ့သတ္မွတ္လိုက္ရင္အဆင္ေျပပါျပီ။
DivisionProcess program (List 1) ထဲမွာ divide method ကိုတည္ေဆာက္မယ္။ divide method ထဲမွာ command-line က ရရွိလာတဲ့ input argument ကိုတြက္ျပီး အေျဖကို ျပသေပးပါမယ္။
“args”ကို အသံုးျပဳတာ အခုက ပထမဆံုးျဖစ္္ပါတယ္။ args ဆိုတာ main method ရဲ့ argument ျဖစ္ပါတယ္။ ဒီအေၾကာင္းကို main subject ရဲ့သင္ခန္းစာမွာရွင္းျပျပီးသြားျပီျဖစ္ပါတယ္။
List 1 – DivisionProcess.java
public class DivisionProcess
{
//A method to return the result that x divide by y
public int divide(int x, int y)
{
int answer = x / y;
return answer;
}
}
List 2 – DivisionTest.java
public class DivisionTest
{
public static void main(String[] args)
{
int x; //dividents
int y; //divisors
int answer; // answer
//convert argument into numerical value
x = Integer.parseInt(args[0]);
y = Integer.parseInt(args[1]);
//carry out division
DivisionProcess divisionProcess = new DivisionProcess();
answer = divisionProcess.divide(x, y);
//display result
System.out.println(x + ” / ” + y + ” = ” + answer);
}
}
ဒီ program ကို compile လုပ္ျပီး ေရွ ့ဆက္ၾကရေအာင္။
အေျဖကို တိတိက်က်ေဖာ္ျပထားပါတယ္။
ကဲ program input ကို ေနာက္တစ္နည္းေျပာင္းျပီး တြက္ခ်က္ၾကည့္ရေအာင္။
123/0 ဆိုတဲ့ input value နဲ ့တြက္ခ်က္ၾကည့္ရေအာင္။
ကြ်န္ေတာ္တို ့နားမလည္တဲ့message ေတြကိုျမင္ရပါလိမ့္မယ္။ဒါ့အျပင္ input value 456/ abc နဲ ့တြက္ခ်က္ၾကည့္ရေအာင္။
program ကေနမတူညီတဲ့ message ကိုျပေပးမွာပါ။ ကြ်န္ေတာ္တို ့ရဲ့program မွာ ဒီလို message ကိုမလိုခ်င္ပါဘူး။
JAVA ကေန ဒီ message ေတြကို “exceptions”အေနနဲ ့ျပေပးျခင္းဘဲျဖစ္ပါတယ္။
မင္းက exceptions message ကို ေသေသခ်ာခ်ာနားမလည္ဘူးဆိုရင္ “error” လို ့စဥ္းစားနုိင္ပါတယ္။
123/0 ကိုတြက္ခ်က္တဲ့အခါမွာ ေအာက္မွာေဖာ္ျပထားတဲ့ exception message ကိုျမင္ရမွာပါ။
“java.lang.ArithmeticException: / by zero”.
JAVA က ပိုင္းေျခ 0 နဲ ့ စားလို ့မရဘူးဆိုတဲ့ဆိုတဲ့ error ကို ျပပါလိမ့္မယ္။
ဒါ့အျပင္ 456/ abc ဆိုတဲ့ input values ကိုတြက္ခ်က္တဲ့အခါ ေအာက္မွာျပထားတဲ့အတိုင္း “exception message” ကိုေတြရမွာပါ။
“java.lang.NumberFormatException: abc”
ဒီ problem ကဘယ္မွာျဖစ္တာလဲဆိုရင္ main method ရဲ့ ေနာက္တစ္လိုင္းမွာ input value တန္ဖိုးကို character ကေန numerical တန္ဖိုးေျပာင္းတဲ့ေနရာမွာျဖစ္ပါတယ္။
y = Integer.parseInt(args[1]);
ဒီ Integer.parseInt method က “456” ကို numerical value အေနနဲ ့ေျပာင္းနိုင္ေပမဲ့ “abc” ဆိုတဲ့ တန္ဖိုးကို numerical value အျဖစ္မေျပာင္းနိုင္ပါဘူး။
Program က argument ေတြကိုလက္ခံရရွိတဲ့အခါမွာ အမ်ိဳးမ်ိဳးေသာ processing ေတြကိုျပဳလုပ္တယ္။ user ေပးတဲ့ argument ေတြက ကြ်န္ေတာ္တို ့ခန္ ့မွန္းမထားတဲ့ argument ေတြလည္းပါလာနိုင္ပါတယ္။ ကြ်န္ေတာ္တို ့ေမွ်ာ္လင့္မထားတဲ့ error message ေတြကိုလည္းေတြ ့နိုင္ပါတယ္။ JAVA မွာ ဒီလိုမ်ိဳးမျဖစ္ေအာင္ဘယ္လိုျပဳလုပ္ၾကမလဲ။
ကြ်န္ေတာ္တို ့ေမွ်ာ္လင့္မထားတဲ့reason ေတြကိုေကာင္းေကာင္းနည္းမလည္တဲ့message ေတြကိုျမင္ရတာအဆင္မေျပပါဘူး။ Java မွာ error မျဖစ္ေအာင္
ကြ်န္ေတာ္တို ့ဘယ္လိုလုပ္ရင္အဆင္ေျပနိုင္မလဲ။
user ရဲ့input ကို စစ္ေဆးလိုက္တယ္ဆိုရင္ အဆင္ေျပသြားပါျပီ။
Divisor ကzero ျဖစ္တဲ့အခ်ိန္မွာ ပိုျပီးရွင္းလင္းတဲ့ error ကိုျပနိုင္ဖို ့ program ကို ျပင္လိုက္ၾကရေအာင္။
List 3 – DivisionTest.java
public class DivisionTest
{
public static void main(String[] args)
{
int x; //divident
int y; //divisor
int answer; // answer
//convert argument into numerical value
x = Integer.parseInt(args[0]);
y = Integer.parseInt(args[1]);
if(y == 0)
{
System.out.println(” error: cannot divide by 0! “);
return;
}
//carry out division
DivisionProcess divisionProcess = new DivisionProcess();
answer = divisionProcess.divide(x, y);
//display result
System.out.println(x + ” / ” + y + ” = ” + answer);
}
}
List 3 ကိုcompile လုပ္ပါ။ မၾကာခင္က calculate လုပ္ထားတဲ့123/0 ကိုျပန္တြက္ခ်က္ၾကည့္ရေအာင္။
အခုဆိုရင္ကြ်န္ေတာ္တို ့ျပင္ဆင္ထားတဲ့အတိုင္း error message ကိုျမင္ရပါလိမ့္မယ္။
တကယ္လို ့ကြ်န္ေတာ္တို ့ေမွ်ာ္လင့္ထားတဲ့ character string ကသာ 456/ abc ျဖစ္မယ္ဆိုရင္ ဒါမွမဟုတ္ argument တစ္ခုဘဲေပးမယ္ဆိုရင္ ကြ်န္ေတာ္တို ့ဘယ္လိုလုပ္ရင္ေကာင္းမလဲ?
ကြ်န္ေတာ္တို ့က judgment sentence ကို အျမဲတမ္းမျဖစ္မေနထည့္ေပးရပါမယ္။
အဲဒီလိုနည္းလမ္းနဲ ့အမ်ိဳးမ်ိဳးေသာအေျခအေနေတြကိုသင့္ေတာ္သလို judgment sentence ထည့္ျပီး program ကို ေရးမယ္ဆိုရင္ ခက္ခဲပါတယ္။ တကယ္လို ့ကြ်န္ေတာ္တို ့ဟာ ကိုယ့္ program ကို ကိုယ့္ဘာသာအသံုးျပဳမယ္ဆိုရင္ေတာ့ ဒီအခ်က္ေတြကို ခ်န္ထားခဲ့လို ့ရပါတယ္။ ဒါေပမဲ့ program က လူအမ်ားအသံုးျပဳဖို ့အတြက္ ရည္ရြယ္တဲ့product ဆိုရင္ေတာ့ အဆင္မေျပနိုင္ပါဘူး။
ဒါေပမဲ့ ကြ်န္ေတာ္တို ့program တစ္ပုဒ္ကိုေရးတဲ့အခါ အေျခအေနအားလံုးနဲ ့အဆင္ေျပေအာင္ေရးနိုင္ရပါမယ္။
ဒီexample မွာဆိုရင္ ကြ်န္ေတာ္တို့တကယ္ computer ကိုအလုပ္လုပ္ေစခ်င္တာက divide method တစ္ခုတည္းပါ။ဒါေပမဲ့ divide method ထက္ပိုျပီး error processing အေၾကာင္းကို အမ်ားၾကီးေရးရပါတယ္။
တကယ္လို့အေပၚမွာေဖာ္ျပခဲ့သလို error case နွစ္ခုဘဲဆိုရင္ အဆင္ေျပပါတယ္။ ဒါေပမဲ့ abnormality system တစ္ခုကိုစဥ္းစားၾကည့္မယ္ဆိုရင္ေတာ့ error ေတြက အကန္ ့အသတ္မရွိပါဘူး။
ဒီေနရာမွာ exception process ျဖစ္ေပၚလာမယ္။ ကြ်န္ေတာ္တို ့အေပၚမွာ ျမင္ေတြ ့ခဲ့ရတဲ့ error ကို exception လို ့ပါတယ္။
JAVA က ပိုင္းေျခကို 0 နွင့္စားျခင္း ဒါမွမဟုတ္ abc ကို ကိန္းဂဏန္း တန္ဖိုးကို ေျပာင္းတဲ့အခါမွာ “exception” ကို generate လုပ္ေပးပါတယ္။Exception အမ်ိဳးစားေတြ အမ်ားၾကီးရွိပါတယ္။ Exception အမ်ိဳးအစားေတြအရ ကြ်န္ေတာ္တို ့က ပံုမွန္မဟုတ္အေၾကာင္းအရာေတြကို သိနိုင္ပါတယ္။
တကယ္လို ့program ထဲမွာ exception ကို catch မလုပ္ထားဘူးဆိုရင္ JAVA က ဘယ္လိုလုပ္ရမလဲဆိုတာနားလည္မွာမဟုတ္ပါဘူး။ျပီးေတာ့ ဥပမာ List 1 မွာ ေဖာ္ျပထားတဲ့အတိုင္း exception message ကို display လုပ္မွာျဖစ္ျပီး program ကို stop လုပ္မွာျဖစ္ပါတယ္။
ေအာက္ေဖာ္ျပပါ list ကေတာ့ exception ရဲ့small examples ကို JAVA ျဖင့္ျပင္ဆင္ထားျခင္းဘဲျဖစ္ပါတယ္။ Exception မွာအမ်ိဳးအစားေတြအမ်ားၾကီးရွိပါတယ္။ ဒါေပမဲ့ မၾကာခဏအသံုးျပဳေလ့ရွိတဲ့ exception ေတြကိုကန့္သက္ခ်က္ေတြရွိပါတယ္။
လိုအပ္ခ်က္ေတြအေပၚမူတည္ျပီးေလ့လာမယ္ဆိုရင္ထိေရာက္မူပိုရွိနိင္ပါတယ္။
<Exception အေၾကာင္းအရာမ်ား>
ArithmeticException : ပိုင္းေ၀ကို သုညနဲ ့စားတဲ့အခ်ိန္မွာ
NumberFormatException: character string ကို number အျဖစ္သို ့ေျပာင္းလို ့မရတဲ့အေျခအေနမွာ
ArrayIndexOutOfBoundsException: sequence ထက္ေက်ာ္ျပီးလက္ခံတဲ့အခ်ိန္မွာ
ပထမဆံုးအေနနဲ ့List 3 ကို exception processing နဲ ့အသစ္ျပန္ေရးၾကရေအာင္
List 4 – DivisionTest.java
public class DivisionTest
{
public static void main(String[] args)
{
int x; //dividents
int y; //divisor
int answer; // answer
try
{
//convert argument into numerical value
x = Integer.parseInt(args[0]);
y = Integer.parseInt(args[1]);
//carry out division
DivisionProcess divisionProcess = new DivisionProcess();
answer = divisionProcess.divide(x, y);
}
catch (NumberFormatException ex)
{
//Processing when the character string that was not numerical value
System.out.println(” error: It is not numerical value! “);
return;
}
catch (ArithmeticException ex)
{
//Processing when we were going to divide it by zero
System.out.println(” error: cannot divide by 0! “);
return;
}
catch (ArrayIndexOutOfBoundsException ex)
{
//Processing when argument was not enough
System.out.println(” error: An argument is insufficient! “);
return;
}
//display result
System.out.println(x + ” / ” + y + ” = ” + answer);
}
}
ဒီ program ထဲမွာ ေနာက္တစ္ပိုင္းကေတာ့ exception processing ၏ အေရးၾကီးေသာ point ျဖစ္ပါတယ္။
Try{} ထဲမွာ exception တစ္ခုကို produce လုပ္နိုင္တဲ့process ကိုေဖာ္ျပထားပါတယ္။
Catch() ရဲ့အစိတ္အပိုင္းတစ္ခု အေပၚမွာ exception ရဲ့ processing ျဖစ္တာကိုေဖာ္ျပထားပါတယ္။
try
{
…
}
catch (…)
{
…
}
List 3 ၏ try sentence မွာ character string မွ numerical value ကိုေျပာင္းတဲ့ process နွင့္ divide method ကို အသံုးျပဳတဲ့ process ကို ေရးထားပါတယ္။
Exception အမ်ိဳးအစားတစ္ခုစီအတြက္ catch sentence ထဲမွာ ေရးထားတဲ့ exception ေတြျဖစ္မယ္ဆိုရင္ ကြ်န္ေတာ္တို ့ဘာလုပ္ရမလဲ
* input argument က numerical value မဟုတ္ဘဲ character string ျဖစ္တဲ့အခါ
* ပိုင္းေ၀တန္ဖိုးကို သုည နဲ ့စားတဲ့အခါ
* Input argument ကမလံုေလာက္တဲ့အခါ
ဒီ exception သံုးခုကိုေတာ့နားလည္သေဘာေပါက္သြားျပီလို ့ထင္ပါတယ္။
တကယ္လို ့ေနာက္ထပ္ exception ေတြသာ ထပ္ရွိမယ္ဆိုရင္ ကြ်န္ေတာ္တို ့ catch sentences ထဲမွာ ထပ္တိုးျပီးထည့္သင့္ပါတယ္။
ဒီနည္းအားျဖင့္ exception processing တစ္ခုကိုသတ္မွတ္ျခင္း နွင့္ process ေတြရဲ့ main subject ေတြကိုေဖာ္ျပဖို ့ရန္ ပိုင္းျခားနိုင္ပါတယ္။ ဒီလိုစဥ္းစားနည္းက Java language တစ္ခုလံုးမွာအသံုးျပဳပါတယ္။
ပထမဆံုး try(try) , အကယ္လို ့မင္းက မ try နိုင္ေတာ့ဘူးဆိုရင္ မင္းစဥ္းစားပါ(catch)
ကဲဒီသင္ခန္းစာကိုအနွစ္ခ်ဳပ္ၾကရေအာင္
အနွစ္ခ်ဳပ္
၁. Error processing ေတြက ခက္ခဲပါတယ္။
၂. Exception ကိုသံုးျပီး error processing ေတြကို smart က်က်ေရးနုိင္ပါတယ္
၃. Exception handling ေတြအတြက္ try catch ကိုသံုးပါ။
အခုအခ်ိန္မွာ မင္းက အျဖစ္မေနလိုအပ္တဲ exception အစိတ္အပိုင္းေလးကိုဘဲေလ့လာတာပါ။ ကြ်န္ေတာ္ အကုန္လံုးကိုမရွင္းျပနိုင္ပါဘူး ဘာျဖစ္လို ့လဲဆိုရင္ exception ေတြကို ေလ့လာဖို ့ကအမ်ားၾကီးရွိလို ့ပါ။
Exception ေတြကို ဘယ္လိုအသံုးျပဳလုပ္ရမလဲဆိုတာ ေနာက္ထပ္တစ္ဆင့္အေနနဲ့နက္နက္နဲနဲေလ့လာၾကပါစို ့။
ဆက္ရန္ => (သင္ခန္းစာ ၁၅ : Input libraries ေတြကုိ သံုးၿခင္း။)