استثناها یا موقعیتهای استثنایی (وضعیتها) به خطاهایی گفته میشود که در یک برنامه در طول عملیات آن رخ میدهند. همه استثناها در جاوا شی هستند. بنابراین، آنها می توانند نه تنها به طور خودکار در هنگام وقوع یک موقعیت استثنایی، بلکه توسط خود توسعه دهنده نیز ایجاد شوند. سلسله مراتب کلاس های استثنا: استثناها به چندین کلاس تقسیم می شوند، اما همه آنها یک جد مشترک دارند - کلاس
Throwable
. نوادگان آن زیر طبقات Exception
و Error
. استثناها ( Exceptions
) نتیجه مشکلات یک برنامه هستند که اصولاً قابل حل و پیش بینی هستند. به عنوان مثال، تقسیم بر صفر در اعداد صحیح اتفاق افتاده است. خطاهای ( Errors
) مشکلات جدی تری هستند که مشخصات جاوا بیان می کند که نباید سعی کنید در برنامه خود آنها را حل کنید زیرا مشکلاتی در سطح JVM هستند. به عنوان مثال، اگر حافظه موجود در ماشین مجازی تمام شده باشد، استثناهایی از این دست رخ می دهد. این برنامه همچنان نمی تواند حافظه اضافی برای JVM فراهم کند. در جاوا، همه استثناها به سه نوع تقسیم میشوند: استثناهای بررسی شده ( checked
) و استثناهای علامتنخورده ( unchecked
) که شامل خطاها ( Errors
) و استثناهای زمان اجرا ( RuntimeExceptions
کلاس نزول Exception
) هستند. استثناهای کنترل شده خطاهایی هستند که می توانند و باید در یک برنامه مدیریت شوند؛ همه فرزندان یک کلاس Exception
(اما نه RuntimeException
) به این نوع تعلق دارند. مدیریت استثناها را می توان با استفاده از عملگرها انجام داد try…catch
یا به قسمت خارجی برنامه منتقل کرد. به عنوان مثال، یک متد میتواند استثناهایی را که در آن رخ میدهند بالاتر در سلسله مراتب فراخوانی بدون رسیدگی به خود، ارسال کند. استثناهای بدون علامت نیازی به مدیریت ندارند، اما در صورت تمایل می توانید استثناهای کلاس را مدیریت کنید RuntimeException
. بیایید برنامه زیر را کامپایل و اجرا کنیم:
class Main {
public static void main(String[] args) {
int a = 4;
System.out.println(a/0);
}
}
پس از راه اندازی، پیام زیر بر روی کنسول نمایش داده می شود:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.main(Main.java:4)
پیام کلاس استثنای رخ داده را نشان می دهد - ArithmeticException
. این استثنا قابل رسیدگی است:
class Main {
public static void main(String[] args) {
int a = 4;
try {
System.out.println(a/0);
} catch (ArithmeticException e) {
System.out.println("Произошла недопустимая арифметическая операция");
}
}
}
اکنون به جای یک پیغام خطای استاندارد، بلوکی اجرا می شود catch
که پارامتر آن شیء e کلاس مربوط به استثناء است (به خود شیء می توان هر نامی داد، اگر بخواهیم به زور پرتاب کنیم لازم است این استثنا را دوباره، به عنوان مثال، به طوری که آن را با کنترل کننده دیگری بررسی می شود). در این مورد، بلوک try
شامل قطعه ای از برنامه است که در آن یک استثنا ممکن است رخ دهد. یکی try
می تواند با چندین بلوک catch با کلاس های استثنا متفاوت مطابقت داشته باشد.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
int[] m = {-1,0,1};
Scanner sc = new Scanner(System.in);
try {
int a = sc.nextInt();
m[a] = 4/a;
System.out.println(m[a]);
} catch (ArithmeticException e) {
System.out.println("Произошла недопустимая арифметическая операция");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Обращение по недопустимому индексу массива");
}
}
}
اگر پس از راه اندازی برنامه ارائه شده، کاربر از صفحه کلید 1 یا 2 وارد شود، برنامه بدون ایجاد هیچ استثنایی اجرا می شود. اگر کاربر 0 را وارد کند، یک استثنا از کلاس رخ می دهد ArithmeticException
و توسط اولین بلوک مدیریت می شود catch
. اگر کاربر عدد 3 را وارد کند، یک استثنا کلاس رخ می دهد ArrayIndexOutOfBoundsException
(آرایه خارج از محدوده)، و توسط بلوک دوم پردازش می شود catch
. اگر کاربر یک عدد غیر صحیح را وارد کند، به عنوان مثال، 3.14، یک استثنا کلاس رخ می دهد InputMismatchException
(عدم تطابق نوع ورودی)، و در قالب خطای استاندارد پرتاب می شود، زیرا ما به هیچ وجه آن را مدیریت نکردیم. با این حال، میتوانید یک کنترلکننده برای کلاس اضافه کنید Exception
، زیرا این کلاس کلاس والد برای همه استثناهای علامتگذاری شده دیگر است، هر یک از آنها (از جمله ) را میگیرد InputMismatchException
.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
int[] m = {-1,0,1};
int a = 1;
Scanner sc = new Scanner(System.in);
try {
a = sc.nextInt();
m[a-1] = 4/a;
System.out.println(m[a]);
} catch (ArithmeticException e) {
System.out.println("Произошла недопустимая арифметическая операция");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Обращение по недопустимому индексу массива");
} catch (Exception e) {
System.out.println("Произошло ещё Howое-то исключение");
}
}
}
از آنجایی که استثناها بر اساس سلسله مراتبی از کلاس ها و زیر کلاس ها ساخته شده اند، ابتدا باید سعی کنید استثناهای خاص تر و تنها پس از آن موارد کلی تر را مدیریت کنید. به این معنی که اگر بلوک را با مدیریت استثنای کلاس در ابتدا (و نه سوم) قرار دهیم Exception
، هرگز هیچ پیام خطایی به جز «یک استثنا دیگر رخ داده است» (همه استثناها بلافاصله توسط این بلوک گرفته میشوند و به باقی مانده). یک اضافه اختیاری به بلوک ها try…catch
می تواند یک بلوک باشد finally
. دستورات قرار داده شده در آن در هر صورت بدون توجه به اینکه استثنایی رخ دهد یا خیر اجرا می شود. علیرغم این واقعیت که وقتی یک استثنا کنترل نشده رخ می دهد، بخشی از برنامه که پس از تولید این استثنا باقی مانده است، اجرا نمی شود. به عنوان مثال، اگر یک استثنا در طول برخی از محاسبات طولانی رخ داده است، finally
می توانید نتایج میانی را در یک بلوک نشان دهید یا ذخیره کنید. پیوند به منبع: استثناها و رسیدگی به آنها
GO TO FULL VERSION