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.
。