Java异常处理
异常处理简介
异常处理是Java中处理程序运行时错误的重要机制,它允许程序优雅地处理错误情况,而不是直接崩溃。
异常的基本概念
// 异常处理的基本结构
try {
// 可能抛出异常的代码
int result = 10 / 0;
} catch (ArithmeticException e) {
// 处理异常
System.out.println("发生算术异常:" + e.getMessage());
} finally {
// 无论是否发生异常都会执行的代码
System.out.println("清理资源");
}
异常类型
Java中的异常分为两大类:Checked Exception(受检异常)和Unchecked Exception(非受检异常)。
// Checked Exception示例
public void readFile() throws IOException {
FileReader reader = new FileReader("file.txt");
// 读取文件内容
reader.close();
}
// Unchecked Exception示例
public void divide(int a, int b) {
if (b == 0) {
throw new ArithmeticException("除数不能为零");
}
int result = a / b;
}
try-catch语句
try-catch语句用于捕获和处理异常,可以包含多个catch块来处理不同类型的异常。
public void processData() {
try {
// 可能抛出多种异常的代码
FileInputStream fis = new FileInputStream("data.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Object obj = ois.readObject();
} catch (FileNotFoundException e) {
System.out.println("文件未找到:" + e.getMessage());
} catch (IOException e) {
System.out.println("IO异常:" + e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println("类未找到:" + e.getMessage());
} finally {
// 关闭资源
try {
if (ois != null) ois.close();
if (fis != null) fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
throw和throws关键字
throw用于抛出异常,throws用于声明方法可能抛出的异常。
// 自定义异常类
public class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message);
}
}
// 使用throw和throws
public class Person {
private int age;
public void setAge(int age) throws InvalidAgeException {
if (age < 0 || age > 150) {
throw new InvalidAgeException("年龄必须在0-150之间");
}
this.age = age;
}
public void validateAge(int age) {
try {
setAge(age);
System.out.println("年龄设置成功");
} catch (InvalidAgeException e) {
System.out.println("年龄验证失败:" + e.getMessage());
}
}
}
try-with-resources语句
try-with-resources语句用于自动关闭实现了AutoCloseable接口的资源。
// 使用try-with-resources
public void copyFile(String source, String target) {
try (FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(target)) {
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
} catch (IOException e) {
System.out.println("文件复制失败:" + e.getMessage());
}
}
异常链
异常链允许在捕获一个异常时抛出另一个异常,同时保留原始异常的信息。
public class DataProcessor {
public void processData() throws ProcessingException {
try {
// 处理数据
throw new IOException("数据读取错误");
} catch (IOException e) {
throw new ProcessingException("数据处理失败", e);
}
}
}
public class ProcessingException extends Exception {
public ProcessingException(String message, Throwable cause) {
super(message, cause);
}
}
异常处理最佳实践
良好的异常处理实践可以提高代码的可维护性和可靠性。
// 1. 使用具体的异常类型
try {
// 代码
} catch (FileNotFoundException e) {
// 处理文件未找到异常
} catch (IOException e) {
// 处理其他IO异常
}
// 2. 不要捕获Exception
try {
// 代码
} catch (Exception e) {
// 避免捕获所有异常
}
// 3. 在finally块中释放资源
try {
// 使用资源
} finally {
// 释放资源
}
// 4. 使用try-with-resources
try (Resource resource = new Resource()) {
// 使用资源
}
实践练习
练习1:实现一个安全的文件读取器
public class SafeFileReader {
public String readFile(String filename) {
// 实现安全的文件读取逻辑
// 处理可能出现的异常
}
}