Exception in Java(try-catch)
توضیحات جلسه
جزوه و مستندات
مفاهیم کلیدی
try-catch
اصلیترین و سادهترین ساختار برای کنترل و مدیریت استثناها (Exception Handling) در جاوا است. بلوک try شامل کدهایی است که احتمال بروز خطا در آنها وجود دارد و بلوک catch وظیفه واکنش نشان دادن به آن خطا (مانند چاپ پیام یا لاگ گرفتن) را بر عهده دارد.
ArithmeticException
نوعی استثنا در جاوا که هنگام بروز خطاهای محاسباتی رخ میدهد؛ رایجترین مثال آن تقسیم یک عدد بر صفر (/ by zero) است.
InputMismatchException
این استثنا زمانی رخ میدهد که ورودی دریافت شده از کاربر با نوع دادهای که برنامه انتظار دارد (مثلاً دریافت رشته به جای عدد در کلاس Scanner) مطابقت نداشته باشد.
Stack Trace
گزارشی است که مسیر اجرای برنامه و متدهای فراخوانی شده را تا لحظه وقوع خطا نشان میدهد. این گزارش شامل نام کلاس، نام متد و شماره دقیق خطی است که خطا در آن رخ داده و برای عیبیابی (Debugging) بسیار حیاتی است.
Multiple Catch Blocks
قابلیتی که اجازه میدهد برای یک بلوک try واحد، چندین بلوک catch مختلف بنویسیم تا انواع مختلفی از استثناها را به صورت مجزا مدیریت کنیم.
Union Catch Block
قابلیتی که از جاوا ۷ معرفی شد و اجازه میدهد چندین استثنای مختلف را در یک بلوک catch واحد و با استفاده از عملگر | (OR) مدیریت کنیم تا از تکرار کد جلوگیری شود.
موارد مصاحبه ای
هدف اصلی استفاده از try-catch چیست؟
جلوگیری از مختل شدن روند اجرای برنامه؛ با استفاده از این ساختار، حتی در صورت بروز خطا، برنامه متوقف نشده و میتواند به اجرای کدهای بعد از بلوک مدیریت خطا ادامه دهد.
اگر نوع اکسپشن در کچ با اکسپشن پرتاب شده متفاوت باشد چه میشود؟
در این صورت خطا توسط آن بلوک مدیریت نمیشود و برنامه طوری رفتار میکند که انگار هیچ مدیریتی صورت نگرفته است (برنامه کرش میکند). همیشه باید نوع استثنای مناسب را catch کرد.
نحوه حرکت کنترل برنامه (Execution Flow) در try-catch چگونه است؟
به محض وقوع خطا در بلوک try، اجرای بقیه خطوط آن بلوک متوقف شده و برنامه مستقیماً به بلوک catch مربوطه میپرد. اگر خطایی رخ ندهد، بلوک catch نادیده گرفته میشود.
تفاوت Multiple Catch با Union Catch در چیست؟
در Multiple Catch برای هر اکسپشن یک بلوک جداگانه با دستورات متفاوت داریم، اما در Union Catch چندین اکسپشن را در یک ورودی catch کرده و معمولاً واکنش یکسانی به همه آنها نشان میدهیم.
آیا چاپ Stack Trace در محیط عملیاتی (Production) توصیه میشود؟
خیر؛ چاپ کامل استثنا با متد printStackTrace() به دلیل حجم زیاد اطلاعات و مسائل امنیتی در برنامههای بزرگ و واقعی استاندارد نیست، اما برای عیبیابی در مرحله توسعه بسیار مفید است.
سناریو کاربردی
در یک برنامه ساده که عدد ۱۰ را بر ورودی دریافت شده از کاربر تقسیم میکند، دو سناریوی خطای احتمالی وجود دارد:
۱. تقسیم بر صفر: اگر کاربر عدد ۰ را وارد کند، ArithmeticException رخ میدهد. با قرار دادن عملیات تقسیم در try و نوشتن یک catch برای این استثنا، میتوانیم پیامی مبنی بر غیرمجاز بودن تقسیم بر صفر به کاربر نشان دهیم بدون اینکه برنامه کرش کند.
۲. ورودی نامعتبر: اگر کاربر به جای عدد، متن وارد کند، متد nextInt() در کلاس Scanner استثنای InputMismatchException را پرتاب میکند. با اضافه کردن یک بلوک catch دیگر، میتوانیم از کاربر بخواهیم که فقط عدد وارد کند. در هر دو حالت، با مدیریت صحیح، عبارت "پایان برنامه" در انتهای کد همیشه چاپ خواهد شد.
بیشتر بدانید
IDE Tip
در محیط IntelliJ، اگر روی خطی که خطا میدهد کلیک کنید و از قابلیتهای پیشنهادی استفاده کنید، خود IDE میتواند بلوک catch مناسب را برای شما تولید کند.
متد getMessage
شیء اکسپشن (معمولاً با نام e یا i) دارای متدی به نام getMessage() است که شرح کوتاهی از علت خطا را به صورت رشته برمیگرداند.
استفاده از instanceof
در مواقعی که از Union Catch استفاده میکنید، میتوانید با دستور instanceof داخل بلوک catch تشخیص دهید که دقیقاً کدام نوع اکسپشن رخ داده است تا رفتار متفاوتی نشان دهید.
محدوده متغیرها (Scope)
توجه داشته باشید متغیرهایی که داخل بلوک try تعریف میشوند، خارج از آن (مثلاً در بلوک catch یا بعد از آن) قابل دسترسی نیستند. برای دسترسی عمومی، باید متغیر را قبل از try تعریف کنید.
