Java 中的異常型別及其處理
我們將瞭解 Java 中的異常型別及其處理。我們將在定義級別看到內建和使用者定義的異常,並通過編寫程式碼示例來理解它們。
Java 中的異常型別及其處理
異常是程式執行過程中發生的意外事件,擾亂了程式的正常執行流程,導致程式異常終止。作為計算機程式設計師,我們可以在我們的程式中處理這些異常。
以下是 Java 異常的層次結構。
Java 有一些與其不同的類庫相關的內建異常。Java 還允許使用者根據他們的專案要求編寫他們的異常。
例外情況按下面列出的兩種方式進行分類。
- 內建異常
1.1 檢查異常
1.2 未經檢查的異常 - 使用者自定義異常
這些異常可以使用 try-catch
塊來處理。讓我們從理論上和實踐上理解它們中的每一個。
Java 中的內建異常
Java 庫中已經可以訪問的異常稱為內建異常。這些對於演示特定的錯誤情況非常有用;例如,當程式找不到預期的檔案時會發生 FileNotFoundException
。
內建異常進一步分為兩類,Checked Exceptions 和 Unchecked Exceptions。讓我們深入瞭解它們中的每一個。
Java 中的檢查異常
檢查的異常被稱為 IOExceptions
。這些也稱為編譯時異常,因為編譯器可以在編譯時檢查這些異常。
編譯器確保計算機程式設計師已處理異常以避免程式終止。
有必要處理這些異常;否則,程式將無法編譯,並會產生編譯錯誤。下面列出了一些檢查的異常。
ClassNotFoundException
- 當我們嘗試訪問未定義的類時發生。或者我們可以說誰的定義不可用。InterruptedException
- 當執行緒在等待、休眠或處理過程中被中斷時發生。InstantiationException
- 當我們嘗試建立類的物件(例項)但未能例項化時發生。IOException
- 只要 IO(輸入-輸出)操作中斷或失敗,就會發生此異常。FileNotFoundException
- 當程式找不到指定的檔案時發生。
下面給出程式碼示例進行練習。
示例程式碼(對於 ClassNotFoundException
):
public class Test {
public static void main(String args[]) {
try {
// the forName() looks for the class "ABC" whose definition
// is missing here
Class.forName("ABC");
} catch (ClassNotFoundException e) {
System.out.println("The ClassNotFoundException exception has been raised.");
}
}
}
輸出:
The ClassNotFoundException exception has been raised.
示例程式碼(用於 InterruptedException
):
class practiceClass extends Thread {
public void run() {
try {
for (int i = 0; i < 5; i++) {
// current thread sleeps to give another
// thread an opportunity to execute
System.out.println("Child Thread is being executed.");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("InterruptedException has been raised.");
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
// instance of praticeClass
practiceClass thread = new practiceClass();
// start thread
thread.start();
// interrupt thread
thread.interrupt();
System.out.println("The execution of the Main thread was accomplished.");
}
}
輸出:
The execution of the Main thread was accomplished.
Child Thread is being executed.
InterruptedException has been raised.
示例程式碼(用於 InstantiationException
):
// we can't instantiate this class
// because it has a private constructor
class practiceClass {
private practiceClass() {}
}
public class Test {
public static void main(String args[]) {
try {
practiceClass c = new practiceClass();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
輸出:
/Test.java:11: error: practiceClass() has private access in practiceClass
practiceClass c = new practiceClass();
^
1 error
示例程式碼(用於 IOException
):
import java.io.*;
public class Test {
public static void main(String args[]) {
FileInputStream file = null;
try {
file = new FileInputStream("E:/Test/Hello.txt");
} catch (FileNotFoundException e) {
System.out.println("File Not Found!");
}
int i;
try {
while ((i = file.read()) != -1) {
System.out.print((char) i);
}
file.close();
} catch (IOException e) {
System.out.println("I/O Exception has occurred.");
}
}
}
輸出:
File Not Found!
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.io.FileInputStream.read()" because "<local1>" is null
at Test.main(Test.java:13)
示例程式碼(對於 FileNotFoundException
):
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
public class Test {
public static void main(String args[]) {
try {
// The specified file doesn't exist in the machine
File file = new File("E://test.txt");
FileReader fileReader = new FileReader(file);
} catch (FileNotFoundException e) {
System.out.println("The specified file does not exist.");
}
}
}
輸出:
The specified file does not exist.
Java 中的未經檢查的異常
未檢查異常與已檢查異常相反,即使我們沒有正確處理它們,在編譯時也不會檢測到它們。通常,當使用者在與程式互動時提供了錯誤資料時,就會發生此類異常。
未經檢查的異常,也稱為執行時異常,是由於程式中的錯誤而發生的。下面列出了一些未經檢查的異常。
ArithmeticException
- 當在算術運算中發現意外情況時發生,例如,將數字除以零。ClassCastException
- 當我們試圖不恰當地將一個類從一種型別轉換為另一種型別時發生。NullPointerException
- 當程式引用null
物件的成員時引發。ArrayIndexOutOfBoundsException
- 當我們嘗試訪問無效索引處的元素時發生。ArrayStoreException
- 當我們嘗試將物件的不正確型別儲存到物件陣列中時引發。
讓我們通過下面給出的程式碼示例來理解它們。
示例程式碼(用於 ArithmeticException
):
public class Test {
public static void main(String args[]) {
try {
int num1 = 5, num2 = 0;
System.out.println("Answer = " + num1 / num2);
} catch (ArithmeticException e) {
System.out.println("Division by 0 is not allowed.");
}
}
}
輸出:
Division by 0 is not allowed.
示例程式碼(用於 ClassCastException
):
public class Test {
public static void main(String[] args) {
try {
Object object = new Integer(1000);
System.out.println((String) object);
} catch (ClassCastException e) {
System.out.println("The Object can't be converted to String.");
}
}
}
輸出:
The Object can't be converted to String.
示例程式碼(用於 NullPointerException
):
public class Test {
public static void main(String args[]) {
try {
String message = null;
System.out.println(message.charAt(0));
} catch (NullPointerException e) {
System.out.println("NullPointerException has been raised.");
}
}
}
輸出:
NullPointerException has been raised.
示例程式碼(對於 ArrayIndexOutOfBoundsException
):
public class Test {
public static void main(String args[]) {
try {
int array[] = new int[5];
for (int i = 0; i < array.length; i++) array[i] = i;
System.out.println(array[6]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBoundsException has occurred.");
}
}
}
輸出:
ArrayIndexOutOfBoundsException has occurred.
示例程式碼(用於 ArrayStoreException
):
public class Test {
public static void main(String args[]) {
try {
Number[] array = new Double[3];
array[0] = new Integer(5);
} catch (ArrayStoreException e) {
System.out.println("You're allowed to store Double Type numbers only.");
}
}
}
輸出:
You're allowed to store Double Type numbers only.
Java 中使用者定義的異常
在某些情況下,內建異常不會按預期發揮作用。為此,使用者(計算機程式設計師)必須通過擴充套件 Exception
類並考慮專案需求來定義他們的異常,這個異常稱為使用者定義的異常。
讓我們編寫一個程式,當分數低於 50 時丟擲異常。
示例程式碼(使用者定義的異常):
public class userDefinedException extends Exception {
// store students' roll numbers
private static int rollNumber[] = {101, 102, 103, 104};
// store students' names
private static String firstname[] = {"Sara", "John", "Jelly", "Daniel"};
// store students' obtained marks
private static double marks[] = {80.00, 70.00, 65.0, 49.00};
// write default constructor
userDefinedException() {}
// write parametrized constructor
userDefinedException(String str) {
super(str);
}
// write main method
public static void main(String[] args) {
try {
// write table's header
System.out.println("Roll#"
+ "\t"
+ "Student"
+ "\t"
+ "Marks");
// display the actual information using loop
for (int i = 0; i < marks.length; i++) {
System.out.println(rollNumber[i] + "\t\t" + firstname[i] + "\t" + marks[i]);
// display user-defined exception if marks < 50
if (marks[i] < 50) {
userDefinedException me = new userDefinedException("The marks are less than 50.");
throw me;
}
}
} catch (userDefinedException e) {
e.printStackTrace();
}
}
}
輸出:
Roll# Student Marks
101 Sara 80.0
102 John 70.0
103 Jelly 65.0
104 Daniel 49.0
userDefinedException: The marks are less than 50.
at userDefinedException.main(userDefinedException.java:26)
如果任何一個學生的分數低於 50 分,這個程式就會丟擲異常,說 The marks are less than 50.
。