ข้อยกเว้นหรือสถานการณ์พิเศษ (สถานะ) คือข้อผิดพลาดที่เกิดขึ้นในโปรแกรมระหว่างการดำเนินการ ข้อยกเว้นทั้งหมดใน Java คืออ็อบเจ็กต์ ดังนั้นจึงสามารถสร้างขึ้นได้ไม่เพียงแต่โดยอัตโนมัติเมื่อเกิดสถานการณ์พิเศษเท่านั้น แต่ยังสร้างขึ้นโดยนักพัฒนาเองด้วย ลำดับชั้นของคลาสข้อยกเว้น: ข้อยกเว้นแบ่งออกเป็นหลายคลาส แต่ทั้งหมดมีบรรพบุรุษร่วมกัน -
Throwable
คลาส ทายาทของมันคือคลาสย่อยException
และError
. ข้อยกเว้น ( Exceptions
) เป็นผลมาจากปัญหาในโปรแกรมซึ่งตามหลักการแล้วสามารถแก้ไขได้และคาดเดาได้ ตัวอย่างเช่น การหารด้วยศูนย์เกิดขึ้นในจำนวนเต็ม ข้อผิดพลาด ( Errors
) เป็นปัญหาร้ายแรงกว่าที่ข้อกำหนดเฉพาะของ Java ระบุว่าคุณไม่ควรพยายามจัดการในโปรแกรมของคุณเอง เนื่องจากเป็นปัญหาระดับ JVM ตัวอย่างเช่น ข้อยกเว้นประเภทนี้เกิดขึ้นหากหน่วยความจำที่พร้อมใช้งานสำหรับเครื่องเสมือนหมด โปรแกรมจะยังคงไม่สามารถจัดเตรียมหน่วยความจำเพิ่มเติมสำหรับ JVM ได้ ใน Java ข้อยกเว้นทั้งหมดแบ่งออกเป็นสามประเภท: ข้อยกเว้นที่ถูกตรวจสอบ ( 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