第七章:异常处理
7.1 Java 异常层次结构
Java 的异常类继承自 Throwable 类,Throwable 类有两个子类:
Error:表示 Java 虚拟机的错误(如 OutOfMemoryError 等),通常是程序无法恢复的错误。
Exception:表示程序中可以捕获并处理的异常,分为两种类型:
Checked Exception:编译时检查异常,需要在代码中显式处理。
Unchecked Exception:运行时异常,不强制要求处理。
异常类的继承层次结构如下:
Throwable
├── Error
└── Exception
├── IOException
├── SQLException
└── RuntimeException
├── NullPointerException
└── ArithmeticException
Error 类通常由 JVM 抛出,不适合程序员捕获。
Exception 类是程序员需要处理的异常。
RuntimeException 是一种 Unchecked Exception,编译器不强制要求捕获或处理。
7.2 Checked Exception vs. Unchecked Exception
7.2.1 Checked Exception(编译时异常)
Checked 异常是指编译器要求程序员必须显式处理的异常。这些异常继承自 Exception 类,但不属于 RuntimeException 类。
常见的 Checked 异常有:
IOException:输入输出操作失败。
SQLException:SQL 执行错误。
FileNotFoundException:文件未找到。
例如,如果你调用某个方法,可能会抛出 IOException,编译器会强制要求你处理它。
import java.io.*;
public class CheckedExceptionExample {
public static void main(String[] args) {
try {
FileReader file = new FileReader("nonexistentfile.txt");
} catch (IOException e) {
System.out.println("Caught an IOException: " + e.getMessage());
}
}
}
7.2.2 Unchecked Exception(运行时异常)
Unchecked 异常是指不需要显式捕获的异常,通常是由于程序错误导致的异常。这些异常继承自 RuntimeException 类。
常见的 Unchecked 异常有:
NullPointerException:空指针异常。
ArithmeticException:算术运算异常(如除以零)。
ArrayIndexOutOfBoundsException:数组下标越界。
这些异常通常发生在运行时,编译器不会要求处理它们。
public class UncheckedExceptionExample {
public static void main(String[] args) {
int result = 10 / 0; // 会抛出 ArithmeticException
}
}
7.3 try-catch-finally 机制
7.3.1 try-catch 语句
try 块用于编写可能会抛出异常的代码,catch 块用于捕获异常并进行处理。如果发生异常,catch 块会执行;如果没有异常发生,catch 块会被跳过。
public class TryCatchExample {
public static void main(String[] args) {
try {
int[] arr = new int[2];
arr[5] = 10; // 会抛出 ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Caught an ArrayIndexOutOfBoundsException: " + e.getMessage());
}
}
}
7.3.2 finally 块
finally 块用于在 try 和 catch 块执行完毕后执行,通常用于资源清理(如关闭文件、数据库连接等)。finally 块总会执行,无论是否有异常发生。
public class FinallyExample {
public static void main(String[] args) {
try {
System.out.println("In try block.");
} catch (Exception e) {
System.out.println("In catch block.");
} finally {
System.out.println("In finally block.");
}
}
}
输出:
In try block.
In finally block.
7.4 throws 和 throw 关键字
7.4.1 throw 关键字
throw 关键字用于抛出一个异常。可以抛出已经创建的异常对象。
public class ThrowExample {
public static void main(String[] args) {
try {
throw new Exception("This is a custom exception.");
} catch (Exception e) {
System.out.println("Caught exception: " + e.getMessage());
}
}
}
7.4.2 throws 关键字
throws 关键字用于在方法声明中指定该方法可能抛出的异常。throws 后面跟着异常类型,可以指定多个异常。
public class ThrowsExample {
public static void main(String[] args) {
try {
method();
} catch (Exception e) {
System.out.println("Caught exception: " + e.getMessage());
}
}
public static void method() throws Exception {
throw new Exception("This method throws an exception.");
}
}
7.5 自定义异常
有时需要根据应用程序的需求创建自己的异常类。自定义异常类通常继承 Exception 类或其子类。
7.5.1 创建自定义异常
public class MyCustomException extends Exception {
public MyCustomException(String message) {
super(message); // 调用父类的构造方法
}
}
public class CustomExceptionExample {
public static void main(String[] args) {
try {
throw new MyCustomException("This is a custom exception.");
} catch (MyCustomException e) {
System.out.println("Caught exception: " + e.getMessage());
}
}
}
7.5.2 自定义运行时异常
如果自定义异常是运行时异常,可以继承 RuntimeException 类。
public class MyRuntimeException extends RuntimeException {
public MyRuntimeException(String message) {
super(message);
}
}
public class RuntimeExceptionExample {
public static void main(String[] args) {
throw new MyRuntimeException("This is a runtime exception.");
}
}
总结
异常层次结构:Java 的异常层次结构分为 Error 和 Exception,Exception 下还有 Checked Exception 和 Unchecked Exception。
Checked Exception 和 Unchecked Exception:Checked 异常需要显式处理,Unchecked 异常则不强制要求处理。
异常处理机制:使用 try-catch 捕获并处理异常,finally 用于资源清理。
throws 和 throw 关键字:throw 用于抛出异常,throws 用于声明方法可能抛出的异常。
自定义异常:可以自定义异常类,通过继承 Exception 或 RuntimeException 来创建适合自己需求的异常类型。
掌握异常处理是编写健壮 Java 程序的重要部分,它能帮助开发者在运行时捕获和处理错误,从而避免程序崩溃。