


مدیریت خطا/Exception Handling در Java
خطاها در دنیای نرم افزار همیشه اتفاق میافتند. این خطاها ممکن است شامل یک ورودی کاربر نامعتبر یا یک سیستم خارجی بدون پاسخ و یا یک خطای ساده برنامه نویسی باشد. در همه این شرایط خطاها در زمان اجرا رخ میدهند و برنامه باید آنها را کنترل کند.
خطاها در دنیای نرم افزار همیشه اتفاق میافتند. این خطاها ممکن است شامل یک ورودی کاربر نامعتبر یا یک سیستم خارجی بدون پاسخ و یا یک خطای ساده برنامه نویسی باشد. در بحث آموزش برنامه نویسی بسیار مهم است که خطاها و چگونگی برطرف کردن آن ها را بشناسیم. در همه این شرایط خطاها در زمان اجرا رخ میدهند و برنامه باید آنها را کنترل کند. در غیر این صورت به درستی عمل نکرده و نمیتواند درخواستهای بعدی را پردازش کند. برنامه نویسی جاوا مکانیزم قدرتمندی را فراهم میکند که به شما امکان میدهد رویداد استثنایی( Exception Handling ) را در جایی که رخ داده است را مدیریت کنید. در این مقاله به بررسی انواع مدیریت خطا در جاوا خواهیم پرداخت.
مدیریت خطا چیست؟
مدیریت استثناها ( Exception Handling ) یکی از مهمترین ویژگیهای برنامه نویسی جاوا است که به ما امکان میدهد خطاهای زمان اجرا ناشی از موارد استثنایی را کنترل کنیم. به خطاهای زمان اجرا (Runtime Error) در جاوا، استثنا یا Exception گفته میشود. در این راهنما ما با مواردی که استثنا است، انواع آن، کلاسهای استثنا و نحوه مدیریت موارد استثنا در Java آشنا خواهیم شد.
چرا یک استثنا یا Exception اتفاق میافتد؟
دلایل مختلفی میتواند باعث ایجاد استثنا یک برنامه شود. به عنوان مثال: باز کردن یک پرونده موجود در برنامه شما یا مشکل اتصال شبکه یا دادههای ورودی خطای ارائه شده توسط کاربر و غیره، هرکدام از این موارد میتواند منجر به ایجاد یک استثنا در برنامه جاوا باشد.
مزایای مدیریت استثنا
مدیریت استثنا به برنامه نویس اطمینان میدهد که جریان برنامه با وقوع یک استثنا یا خطا قطع نمیشود. به عنوان مثال اگر یک برنامه دارای چندین عبارت باشد و یک استثنا یا خطا پس از اجرای عبارات خاص در اواسط راه رخ دهد، عبارات بعد از استثنا اجرا نمیشوند و برنامه به طور ناگهانی خاتمه مییابد. با استفاده از ایجاد مدیریت استثنا اطمینان حاصل میکنیم که تمام دستورات اجرا شده و جریان برنامه شکسته نشود.
چگونگی مدیریت استثنا در جاوا
جاوا دو گزینه مختلف برای رسیدگی و مدیریت استثنا ارائه میدهد. شما می توانید برای رسیدگی به انواع استثناها از روشهای try-catch-end یا try-with-source استفاده کنید که به شما امکان میدهد تا روشهای اجرای برنامه درست را مدیریت کنید.
try-catch-end
این رویکرد کلاسیک برای مدیریت یک استثنا در جاوا است. این روش می تواند شامل 3 مرحله باشد:
- یک بلوک try که بخش کد را در بر میگیرد که ممکن است یک استثنا را ایجاد کند.
- یک یا چند بلوک گرفتن که استثنا را کنترل میکنند.
- ایجاد بلوکی که پس از اجرای موفقیت آمیز بلوک try یا استفاده از یک استثنا trown اجرا میشود.
The Try Block
بیایید ابتدا در مورد بلوک try صحبت کنیم. این روش بخشی از کد شما را شامل میشود که ممکن است استثنا را ایجاد کند. اگر کد شما بیش از یک مورد استثنا دارد میتوانید از میان گزینههای زیر انتخاب کنید:
- برای هر عبارت از یک بلوک try جداگانه استفاده کنید که میتواند یک استثنا را ایجاد کند.
- برای چندین جمله از یک بلوک try استفاده کنید که ممکن است چندین استثنا را ایجاد کند.
Try-With-Resource
وقتی Java 7 دستور try-with-source را معرفی کرد این روش تغییر کرد. در این روش به طور خودکار تمام منابعی که رابط AutoCloseable را اجرا میکنند بسته میشود این موردی است که در بیشتر نسخههای Java وجود دارد که شما باید آنها را ببندید.
تنها کاری که برای استفاده از این ویژگی باید انجام دهید این است که شی object را در بند try قرار دهید. همچنین باید تمام موارد استثنایی را که ممکن است هنگام بسته شدن منبع ایجاد شود ، مدیریت یا تعیین کنید.
در حالت کلی میتوان برای این بلوک سه بخش کلی تعریف کرد که شامل موارد زیر خواهد بود:
- بلوک try: بخشی از کد است که ممکن است باعث ایجاد خطا شود و در صورتی که خطایی رخ ندهد، تمام کدهای موجود در این بلوک اجرا خواهد شد.
- بلوک catch: این بلوک که ممکن است متشکل از چندین بلوک نیز باشد برای مدیریت خطاهایی است که ممکن است در بخش قبلی رخ دهد. معمولاً هر بلوک را برای یک نوع خطا در نظر میگیرند.
- بلوک finally: کدهای موجود در این بلوک پس از اجرای موفق یا ناموفق بلوک try اجرا میشود. (در هر دو حالت بروز خطا یا عدم بروز خطا)
استفاده بلوک finally در try-catch
در صورتی که بخواهیم پس از اجرای با خطا یا بدون خطای یک قطعه کد، عملیات خاصی را در برنامه انجام دهیم مثلا لاگ کردن سیستم، میتوانیم از بلوک finally در ادامه بلوکهای try-catch خود استفاده کنیم.
مدیریت استثنا یا کنترل آن چگونه اتفاق میافتد
در اغلب موارد اگر یک استثنا را کنترل یا تعیین کنید این انتخاب به مورد استفاده بستگی خواهد داشت و همانطور که حدس می زنید ارائه یک راهکار مناسب واحد برای همه موارد استفاده دشوار است.
به طور کلی برای انجام این کار شما باید سوالات زیر را از خود بپرسید:
- آیا می توانید استثنا را با روش فعلی خود کنترل کنید؟
- آیا میتوانید نیازهای همه کاربران کلاس خود را پیشبینی کنید؟ و آیا اجرای استثنا این نیازها را برآورده میکند؟
اگر به هر دو سوال با بله پاسخ دهید ، باید استثنا را در روش فعلی خود کنترل کنید. در همه شرایط دیگر به احتمال زیاد بهتر است آن را مشخص کنید. این امر به شما امکان میدهد تا تماس گیرنده کلاس شما متناسب با مورد استفاده فعلی هندلینگ را اجرا کند.
تولید خطای سفارشی (یا استثنای سفارشی) با کلمه Throw
با استفاده از کلمهی کلیدی throw میتوانید در هر نقطهای از برنامه یک استثنا تولید کنید. در صورتی که این استثنا در یک بلاک try تولید شده باشد، میتوانید در بلاک catch آن را مدیریت کنید. اما در صورتی که استثنا خارج از بلاک try تولید کرده باشید، موجب بروز خطا و توقف برنامه خواهد شد. هر مقداری که مقابل کلمه کلیدی throw قرار داده شود، به عنوان شئ error به بلاک catch ارسال خواهد شد.
البته معمولاً از اشیاء خطای استاندارد برای این منظور استفاده میکنند. یعنی با توجه به نوع استثناء رخ داده، یک شی یا object از نوع مربوطه ایجاد خواهد شد.
شرح تفاوت بین throws و throw
- Throw برای تولید خطای اختصاصی در قالب یک آبجکت exception و ارائه اطلاعات درباره خطا به JVM به کار میرود. در حالی که کلیدواژه throws فقط برای اعلان خطا به کار رفته و مدیریت خطا را به تابع فراخواننده می سپارد.
- خطاهای زمان کامپایل (checked) را نمیتوان به وسیله throw داخل call stack انداخته و از روش بالای stack به روش پایین stack جهت مدیریت انتقال داد. به عبارت دیگر به تنهایی قابل استفاده با خطاهای زمان کامپایل نیست.
خطاهای زمان کامپایل را میتوان با throws داخل call stack قرار داد. به عبارت دیگر به تنهایی با خطاهای زمان کامپایل قابل استفاده میباشد.
- پس از throw کلیدواژه new و اسم کلاسی که آبجکت یا شی خطا از آن ساخته میشود، لحاظ میگردد. در حالی که پس از Throws اسم کلاس ذکر میشود.
- Throw داخل بدنه متد استفاده میشود در حالی که Throws در خط تعریف متد ذکر میشود.
- با کلیدواژه Throw نمیتوانید چندین خطا از جنس کلاسهای مختلف را تولید کنید در حالی که میتوان با Throws چندین خطا، از جنس کلاسهای مختلف مشخص کرد به عنوان مثال: public void method()throws IOException,SQLException
شرح تفاوت بین final، finally و finalize در Java
میتوان تفاوتهای بسیاری بین final، finally و finalize مشخص کرد. در زیر فهرست تفاوتها بین این سه دستور را مشاهده میکنید:
- Final غالبا برای اعمال محدودیت و قید بر روی کلاس، متد و متغیر به کار برده میشود. کلاس final قابل ارثبری نیست، متد final قابل بازنویسی (override) نبوده و مقدار متغیر final قابل ویرایش نخواهد بود. در حالی که Finally یک قطعه کد است که میزبان کدهای مهم بوده و صرف نظر اینکه خطا مدیریت شود یا نشود اجرا خواهد شد و همچنین متد finalize برای آزادسازی منابع سیستمی و عملیات پاکسازی حافظه به کار برده میشود. این متد قبل از اینکه عملیات پاکسازی انجام شده وgarbage collector آبجکتها یا اشیاء را از حافظه پاک کند، توسط JVM فراخوانی میگردد.
- Final یک کلیدواژه است. در حالی که Finally یک قطعه کد است و Finalize یک محسوب میشود.
متدهای مورد استفاده در Exception ها
باید بدانید که همه Exception ها به دلیل اینکه به نوعی زیرمجموعه کلاس Throwable هستند یا به عبارتی از آن ارث میبرند دارای متدهای مشترکی با هم هستند. متدهای مختلفی وجود دارد که از آن میان می توان به پر کاربردترین آنها به شرح زیر اشاره داشت:
- متد getMessage : پیام مرتبط با استثنای رخ داده را در فرمت رشته (String) ارائه میکند.
- متد printStackTrace : نوع خروجی این متد void است و در صورت فراخوانی سلسله مراتب متدهای کلاسهای مختلف که باعث به وجود آمدن و رخداد این خطا شدهاند را در خروجی چاپ میکند. از آنجایی که این تابع مسیر صدا زده شدن توابع مختلف را تا رسیدن به خطای رخ داده نمایش میدهد در فرآیند رفع خطاهای کدها یا دیباگینگ کمک بسیاری میکند.
- متد getStackTrace : همان سلسله مراتب اجرای توابع مختلف تا رسیدن به استثنای رخ داده را در قالب یک آرایه به عنوان خروجی نمایش میدهد.