CodeGym /وبلاگ جاوا /Random-FA /استثنائات: بررسی شده، بدون علامت و سفارشی
John Squirrels
مرحله
San Francisco

استثنائات: بررسی شده، بدون علامت و سفارشی

در گروه منتشر شد
سلام! در درس آخر با استثناها در زبان جاوا آشنا شدیم و نمونه هایی از نحوه کار با آنها را دیدیم. امروز نگاهی عمیق تر به ساختار استثناها خواهیم داشت و یاد می گیریم که چگونه استثناهای خود را بنویسیم :)

انواع استثنائات

همانطور که قبلاً گفتیم، در جاوا استثناهای زیادی وجود دارد، تقریباً 400! اما همه آنها به گروه هایی تقسیم می شوند، بنابراین به خاطر سپردن آنها نسبتاً آسان است. اینطور به نظر می رسد: استثناها: بررسی شده، بدون علامت و سفارشی - 2 همه استثناها یک جد مشترک در Throwableکلاس دارند. دو گروه عمده از آن مشتق شده است: استثناها ( Exception ) و خطاها ( Error ). خطا - این نشان دهنده یک خطای مهم در زمان اجرا مربوط به عملکرد ماشین مجازی جاوا است. در بیشتر موارد، Error نیازی به رسیدگی ندارد، زیرا نشان دهنده برخی نقص های جدی در کد است. معروف ترین آنها StackOverflowError (این اتفاق می افتد، برای مثال، زمانی که یک متد به طور بی پایان خود را فراخوانی می کند) و OutOfMemoryError (این اتفاق زمانی رخ می دهد که حافظه کافی برای ایجاد اشیاء جدید وجود نداشته باشد). همانطور که می بینید، در این شرایط، معمولاً هیچ چیز در زمان اجرا وجود ندارد: کد به سادگی اشتباه نوشته شده است و باید دوباره کار شود. استثنا - این نشان دهنده یک استثنا است: یک موقعیت استثنایی و برنامه ریزی نشده که در حین اجرای برنامه رخ می دهد. آنها به اندازه Error جدی نیستند، اما همچنان نیازمند توجه ما هستند. همه استثناها به 2 نوع تقسیم می شوند: علامت زده و بدون علامت . استثناها: علامت زده، بدون علامت و سفارشی - 3 همه استثناهای بررسی شده از Exceptionکلاس مشتق شده اند. "بررسی" به چه معناست؟ ما در درس آخر به این اشاره کردیم: "بنابراین کامپایلر جاوا رایج ترین استثناها و موقعیت هایی را که ممکن است رخ دهند را می شناسد." به عنوان مثال، می داند که اگر کد داده ها را از یک فایل بخواند، آن فایل به راحتی وجود نخواهد داشت. و بسیاری از چنین موقعیت هایی وجود دارد (که می تواند استنباط کند). بر این اساس، کامپایلر کد ما را از قبل برای وجود این استثناهای بالقوه بررسی می کند. اگر آنها را پیدا کند، تا زمانی که آنها را مدیریت نکنیم یا دوباره آنها را پرتاب نکنیم، کد را کامپایل نمی کند. نوع دوم استثناء "برگزیده" است. آنها برگرفته از RuntimeExceptionکلاس هستند. تفاوت آنها با استثناهای بررسی شده چیست؟ به نظر می رسد که بسیاری از کلاس های مختلف نیز مشتق شده اند RuntimeException(که استثنائات زمان اجرا را توصیف می کنند). تفاوت این است که کامپایلر این خطاها را پیش بینی نمی کند. به نظر می رسد می گوید: "وقتی کد نوشته شد، چیز مشکوکی پیدا نکردم، اما در حین اجرا مشکلی پیش آمد. ظاهراً در کد خطا وجود دارد!" و در واقع این درست است. استثناهای بدون علامت اغلب نتیجه خطاهای برنامه نویس هستند. و بدیهی است که کامپایلر نمی تواند هر موقعیت بدی که ممکن است افراد با دست خود ایجاد کنند را پیش بینی کند. :) بنابراین، بررسی نمی کند که آیا چنین استثناهایی در کد ما مدیریت می شوند یا خیر. قبلاً با چندین استثناء بدون علامت روبرو شده اید:
  • یک ArithmeticException هنگام تقسیم بر صفر رخ می دهد
  • یک ArrayIndexOutOfBoundsException زمانی رخ می دهد که شما سعی می کنید به موقعیتی خارج از آرایه دسترسی پیدا کنید.
البته، می‌توانید تصور کنید که سازندگان جاوا می‌توانستند مدیریت استثنا اجباری را معرفی کنند، اما در این مورد کد بسیار پیچیده خواهد بود. برای هر عملیات تقسیم، آیا باید یک try-catchبلوک بنویسید تا بررسی کنید که آیا تصادفاً بر صفر تقسیم شده اید؟ هر زمان که به یک آرایه دسترسی داشتید، باید یک try-catchبلوک بنویسید تا بررسی کنید که آیا فهرست شما خارج از محدوده است یا خیر. همه چیز کد اسپاگتی خواهد بود و کاملاً غیرقابل خواندن خواهد بود. منطقی است که این ایده کنار گذاشته شد. در نتیجه، استثناهای علامت‌نخورده نیازی به مدیریت در بلوک‌ها یا پرتاب مجدد ندارند try-catch(اگرچه از نظر فنی این امکان وجود دارد، مانند خطا).

چگونه استثنای خود را ایجاد کنید

البته، سازندگان جاوا نمی توانند هر موقعیت استثنایی را که ممکن است در برنامه ها ایجاد شود، پیش بینی کنند. برنامه های زیادی در دنیا وجود دارد و بسیار متنوع هستند. اما این جای نگرانی نیست، زیرا در صورت لزوم می توانید استثناء خود را ایجاد کنید. انجام این کار بسیار آسان است. تنها کاری که باید انجام دهید این است که کلاس خود را ایجاد کنید. باید مطمئن باشید که نام آن با "Exception" ختم می شود. کامپایلر به این نیاز ندارد، اما برنامه نویسان دیگری که کد شما را می خوانند بلافاصله متوجه می شوند که این یک کلاس استثنا است. علاوه بر این، نشان دهید که کلاس از Exceptionکلاس به ارث برده شده است (کامپایلر به این نیاز دارد). مثلاً فرض کنید Dogکلاس داریم. ما می توانیم با استفاده از این روش سگ را پیاده کنیم walk(). اما قبل از انجام این کار، باید بررسی کنیم که آیا حیوان خانگی ما یقه، افسار و پوزه بسته است یا خیر. اگر هر یک از این چرخ دنده گم شده باشد، ما استثنای خود را ایجاد می کنیم: DogIsNotReadyException . کد آن به شکل زیر است:
public class DogIsNotReadyException extends Exception {

   public DogIsNotReadyException(String message) {
       super(message);
   }
}
برای نشان دادن اینکه کلاس یک استثنا است، باید بعد از نام کلاس بنویسید " extsence Exception " (این به معنای "کلاس از کلاس Exception مشتق شده است"). در سازنده، ما به سادگی سازنده کلاس را با پیامException String فراخوانی می کنیم (اگر استثنا رخ دهد، پیام، شرح خطا را به کاربر نشان خواهیم داد). در کد کلاس ما چگونه به نظر می رسد:
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("We're getting ready for a walk!");
   if (isCollarPutOn && isLeashPutOn && isMuzzlePutOn) {
       System.out.println("Hooray, let's go for a walk! " + name + " is very happy!");
   } else {
       throw new DogIsNotReadyException(name + " is not ready for a walk! Check the gear!");
   }
 }

}
اکنون walk()روش ما یک DogIsNotReadyException می اندازد . این کار با کلمه کلیدی پرتاب انجام می شود. همانطور که قبلاً گفتیم، استثنا یک شی است. بنابراین، هنگامی که یک استثنا رخ می دهد (سگ چیزی را از دست می دهد) در روش ما، یک DogIsNotReadyExceptionشی جدید ایجاد می کنیم و با استفاده از کلمه کلیدی throw آن را پرتاب می کنیم. ما " throts DogIsNotReadyException " را به اعلان متد اضافه می کنیم. به عبارت دیگر، اکنون کامپایلر آگاه است که فراخوانی walk()متد می تواند به یک موقعیت استثنایی تبدیل شود. بر این اساس، اگر این متد را در جایی از برنامه خود فراخوانی کنیم، باید این استثنا را مدیریت کنیم. بیایید سعی کنیم این کار را در main()روش انجام دهیم:
public static void main(String[] args) {

   Dog dog = new Dog("Buddy");
   dog.putCollar();
   dog.putMuzzle();
   dog.walk();// Unhandled exception: DogIsNotReadyException
}
این کامپایل نمی شود. استثنا رسیدگی نمی شود! ما کد خود را در یک try-catchبلوک قرار می دهیم تا استثنا را مدیریت کنیم:
public static void main(String[] args) {

   Dog dog = new Dog("Buddy");
   dog.putCollar();
   dog.putMuzzle();
   try {
       dog.walk();
   } catch (DogIsNotReadyException e) {
       System.out.println(e.getMessage());
       System.out.println("Checking the gear! Is the collar on? " + dog.isCollarPutOn + "\r\n Is the leash on? "
       + dog.isLeashPutOn + "\r\n Is the muzzle on? " + dog.isMuzzlePutOn);
   }
}
حالا بیایید به خروجی کنسول نگاه کنیم: یقه روشن است! پوزه روشن است! برای پیاده روی آماده می شویم! بادی برای پیاده روی آماده نیست! دنده را چک کنید! چک کردن دنده! یقه روی آن است؟ درست است آیا افسار بسته است؟ false آیا پوزه روشن است؟ درست است ببینید خروجی کنسول چقدر آموزنده تر بود! ما هر قدم برداشته شده در برنامه را می بینیم. ما می بینیم که خطا کجا رخ داده است، و همچنین می توانیم بلافاصله ببینیم که سگ ما دقیقاً چه چیزی را از دست داده است. :) و اینگونه است که استثناهای خود را ایجاد می کنید. همانطور که می بینید، هیچ چیز پیچیده ای در مورد آن وجود ندارد. و حتی با وجود اینکه سازندگان جاوا به خود زحمت ندادند که در این زبان یک استثنای ویژه برای سگ‌های ضعیف بگنجانند، ما نظارت آنها را برطرف کرده‌ایم. :)
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION