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