دستور try و catch

می توان خطاها را با استفاده از دستور try…catch اداره کرد. بدین صورت که کدی را که احتمال می دهید ایجاد خطا کند در داخل بلوک try قرار می دهید. بلوک catch هم شامل کدهایی است که وقتی اجرا می شوند که برنامه با خطا مواجه شود. تعریف ساده ی این دو بلوک به این صورت است که بلوک try سعی می کند که دستورات را اجرا کند و اگر در بین دستورات خطایی وجود داشته باشد برنامه دستورات مربوط به بخش catch را انجام می دهد. برنامه زیر نحوه استفاده از دستور try…catch را نمایش می دهد :

   1: package myfirstprogram;
   2: 
   3: public class MyFirstProgram 
   4: {
   5:     public static void main(String[] args) 
   6:     { 
   7:         int result;                        
   8:         int x = 5;                         
   9:         int y = 0;                         
  10: 
  11:         try                                                               
  12:         {                                                                 
  13:             result = x / y; //ERROR                                       
  14:         }                                                                 
  15:         catch(ArithmeticException e)                                      
  16:         {                                                                 
  17:             System.out.println("An attempt to divide by 0 was detected.");
  18:         }                                                                 
  19:     }
  20: }
An attempt to divide by 0 was detected.

در داخل بلوک try، مقدار x را که 5 است بر y که مقدار آن 0 است تقسیم کرده ایم. نتیجه محاسبه به وجود آمدن خطای / by zero (عدد تقسیم بر صفر) است. از آنجاییکه در برنامه بالا خطایی به وجود آمده است کدهای داخل بلوک catch اجرا می شوند. بنابراین :

try
{  
    result = x / y; //Error: Jump to catch block
    System.out.println("This line will not be executed.");        
}  
catch(ArithmeticException e)                                      
{                                                                
    System.out.println("An attempt to divide by 0 was detected.");
}  

همانطور که در مثال بالا مشاهده می کنید از یک نوع استثناء مخصوص به یک خطا در داخل بلوک catch که کلاس ArithmeticException است استفاده کرده ایم. همچنین می توانید مقدار استثنا را در داخل یک متغیر قرار داده و سپس آن را نمایش دهید:

try
{
    result = x / y; //ERROR
}
catch(ArithmeticException error)
{
    System.out.println(error.getMessage());
} 
/ by zero

متغیر دارای اطلاعات مفیدی در مورد استثناء به وجود آمده است. برای نمایش اطلاعاتی در مورد استثناء هم از متد getMessage() استفاده می کنیم. همه کلاسهای استثناء توضیحاتی در مورد خطاها می دهند. در درسهای آینده در مورد خصوصیات استثناء ها بیشتر توضیح می دهیم. اگر فکر می کنید که در بلوک try ممکن است با چندین خطا مواجه شوید می توانید از چندین بلوک catch استفاده نمایید ولی به یاد داشته باشید که برای هر کدام از آن خطاها از کلاس استثناء مربوط به هر یک استفاده کنید:

int result;                                
int x = 5;                                 
int y;                                 

try                                        
{
    y = input.nextInt();                                          
    result = x / y; //ERROR                
}
catch(ArithmeticException error)           
{                                          
    System.out.println(error.getMessage());
}
catch(InputMismatchException error)              
{                                          
    System.out.println(error.getMessage());
}  

از انجاییکه مقدار y به وسیله ورودی که از کاربر گرفته می شود ،تعیین می شود، مقدار آن باید با توجه به مثال بالا غیر صفر باشد (عدد تقسیم بر صفر تعریف نشده است). اما یک مشکل وجود دارد.چون ممکن است که کاربر یک مقدار غیر عددی وارد کند (مثلا یک حرف) که در این صورت برنامه نمی تواند حرف را به عدد تبدیل کند و خطای نوع (InputMismatchException) اتفاق می افتد. وقتی استثناء اتفاق افتاد بلوک catch مربوط به این خطا اجرا می شود و محاسبه خارج قسمت تقسیم x بر y نادیده گرفته می شود. قسمت catch کد بالا را به صورت زیر هم می توان نوشت :

catch(ArithmeticException | InputMismatchException error)           
{                                          
    System.out.println(error.getMessage());
}

حال فرض کنید شما می خواهید تمام خطاهای احتمالی که ممکن است در داخل بلوک try اتفاق می افتند را فهمیده و اداره کنید این کار چگونه امکانپذیر است؟ به راحتی و با استفاده از کلاس عمومی Exception می توانید این کار را انجام داد. هر کلاس استثناء در جاوا از این کلاس ارث بری می کند بنابراین شما می توانید هر نوع استثناءیی را در شئی از کلاس Exception ذخیره نمایید.

try
{
    //Put your codes to test here
}
catch (Exception error)
{
    System.out.println(error.Message);
}

با استفاده از این روش دیگر لازم نیست نگران اتفاق خطاهای احتمالی باشید چون بلوک catch برای هر گونه خطایی که در داخل بلوک try تشخیص داده شود پیغام مناسبی نشان می دهد. به این نکته توجه کنید که اگر بخواهید از کلاس پایه Exception همراه با سایر کلاسهای استثناء دیگر که از آن مشتق می شوند در برنامه استفاده کنید باید کلاس پایه Exception در آخرین بلوک catch قرار گیرد.

try
{
    //Put your codes to test here
}
catch (ArithmeticException e)
{
    System.out.println("Division by zero is not allowed.");
}
catch (InputMismatchException e)
{
    System.out.println("Error on converting the data to proper type.");
}
catch (Exception e)                         
{                                           
    System.out.println("An error occured.");
}                                           

اگر کلاس پایه Exception را در اولین بلوک catch قرار دهیم و خطایی در برنامه رخ دهد چون تمام کلاسهای استثناء از این کلاس مشتق می شوند در نتیجه اولین بلوک catch اجرا شده و سایر بلوک ها حتی با وجود اینکه خطای مورد نظر به آنها مربوط باشد اجرا نمی شوند.