异常层次结构
Java的异常层次结构从java.lang.Throwable
类开始。Throwable
类有两个重要的子类:Exception
和 Error
。
- Error:表示应用程序无法处理的严重问题,通常是虚拟机相关的问题,比如内存不足(
OutOfMemoryError
)等。程序不应该尝试捕获这些异常。 - Exception:表示应用程序可以捕获并处理的异常。
Exception
类又可以分为两类:- 已检查异常 (Checked Exception):在编译时必须被显式处理。通常是可以预见的异常,需要明确的处理逻辑。
- 未检查异常 (Unchecked Exception):也叫运行时异常,继承自
RuntimeException
。通常是编程错误引起的,比如空指针异常、数组越界等。
详细示例和解释
我们将详细探讨每个部分,并提供相关示例代码。
1. try
块
try
块包含可能会抛出异常的代码。如果在try
块中发生了异常,程序会立即跳到相应的catch
块,不会继续执行try
块中的剩余代码。
try {
int result = 10 / 0; // 这会抛出ArithmeticException
System.out.println("This will not be printed");
} catch (ArithmeticException e) {
System.out.println("ArithmeticException caught: " + e.getMessage());
}
2. catch
块
catch
块用来捕获和处理try
块中抛出的异常。可以有多个catch
块来处理不同类型的异常。
try {
int[] numbers = new int[3];
numbers[5] = 10; // 这会抛出ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBoundsException caught: " + e.getMessage());
}
3. finally
块
finally
块中的代码无论是否发生异常都会执行。它通常用来清理资源,比如关闭文件、释放数据库连接等。
FileReader fr = null;
try {
fr = new FileReader("test.txt");
// 读取文件的代码
} catch (FileNotFoundException e) {
System.out.println("FileNotFoundException caught: " + e.getMessage());
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
System.out.println("IOException caught while closing FileReader: " + e.getMessage());
}
}
}
4. throw
语句
throw
语句用于显式地抛出一个异常。你可以创建一个异常对象,并使用throw
语句将其抛出。
public static void checkAge(int age) {
if (age < 18) {
throw new IllegalArgumentException("Age must be at least 18");
}
}
public static void main(String[] args) {
try {
checkAge(15);
} catch (IllegalArgumentException e) {
System.out.println("Exception caught: " + e.getMessage());
}
}
5. throws
关键字
throws
关键字用于在方法签名中声明该方法可能抛出的异常。这是必须的,以便调用者可以知道该方法可能抛出的异常并做出相应处理。
public static void readFile(String fileName) throws IOException {
File file = new File(fileName);
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
fr.close();
}
public static void main(String[] args) {
try {
readFile("test.txt");
} catch (IOException e) {
System.out.println("IOException caught: " + e.getMessage());
}
}
自定义异常
在特定业务场景下,定义自定义异常可以提供更具体的错误信息。创建一个自定义异常需要继承Exception
类或其子类。
class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message);
}
}
public class CustomExceptionExample {
public static void checkAge(int age) throws InvalidAgeException {
if (age < 18) {
throw new InvalidAgeException("Age must be at least 18");
}
}
public static void main(String[] args) {
try {
checkAge(15);
} catch (InvalidAgeException e) {
System.out.println("InvalidAgeException caught: " + e.getMessage());
}
}
}
总结
Java的异常处理机制是一个强大的工具,可以帮助开发者更好地管理和处理程序中的错误和异常情况。通过使用try-catch
块、finally
块、throw
语句和throws
关键字,你可以编写更健壮和可靠的代码。同时,自定义异常可以使你的代码更具可读性和可维护性。