Appearance
⚠️ 异常处理
异常概述
异常(Exception)是程序运行过程中发生的错误或异常情况。Java 提供了完善的异常处理机制。
异常类型
- Error:系统错误,程序无法处理
- Exception:程序异常,可以处理
- RuntimeException:运行时异常(非检查异常)
- 其他 Exception:检查异常
异常类层次结构
Throwable
├── Error
│ ├── OutOfMemoryError
│ ├── StackOverflowError
│ └── ...
└── Exception
├── RuntimeException
│ ├── NullPointerException
│ ├── ArrayIndexOutOfBoundsException
│ ├── IllegalArgumentException
│ └── ...
└── 其他 Exception
├── IOException
├── SQLException
└── ...try-catch-finally
基本语法
java
try {
// 可能抛出异常的代码
} catch (ExceptionType e) {
// 处理异常
} finally {
// 无论是否发生异常都会执行的代码
}示例
java
try {
int result = 10 / 0; // 抛出 ArithmeticException
} catch (ArithmeticException e) {
System.out.println("除数不能为0: " + e.getMessage());
} finally {
System.out.println("finally 块执行");
}多个 catch
java
try {
int[] arr = new int[5];
arr[10] = 5; // 可能抛出 ArrayIndexOutOfBoundsException
int result = 10 / 0; // 可能抛出 ArithmeticException
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数组索引越界: " + e.getMessage());
} catch (ArithmeticException e) {
System.out.println("算术异常: " + e.getMessage());
} catch (Exception e) {
System.out.println("其他异常: " + e.getMessage());
}try-with-resources(Java 7+)
java
try (FileInputStream fis = new FileInputStream("file.txt")) {
// 使用资源
int data = fis.read();
} catch (IOException e) {
System.out.println("IO 异常: " + e.getMessage());
}
// 资源自动关闭throws 关键字
抛出异常
java
public void method() throws IOException {
throw new IOException("IO 错误");
}
// 调用方法需要处理异常
try {
method();
} catch (IOException e) {
System.out.println("捕获异常: " + e.getMessage());
}方法声明
java
public void readFile(String filename) throws IOException {
FileInputStream fis = new FileInputStream(filename);
// 读取文件
}
// 调用者必须处理异常
public void processFile() {
try {
readFile("file.txt");
} catch (IOException e) {
System.out.println("文件读取失败: " + e.getMessage());
}
}throw 关键字
抛出异常
java
public void validateAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("年龄必须在 0-150 之间");
}
}
// 使用
try {
validateAge(-1);
} catch (IllegalArgumentException e) {
System.out.println("验证失败: " + e.getMessage());
}自定义异常
java
// 自定义异常类
public class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
// 使用
public void method() throws CustomException {
throw new CustomException("自定义异常");
}常见异常类型
RuntimeException(运行时异常)
java
// NullPointerException
String str = null;
int length = str.length(); // 抛出 NullPointerException
// ArrayIndexOutOfBoundsException
int[] arr = new int[5];
int value = arr[10]; // 抛出 ArrayIndexOutOfBoundsException
// IllegalArgumentException
public void setAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数");
}
}
// NumberFormatException
int num = Integer.parseInt("abc"); // 抛出 NumberFormatException
// ClassCastException
Object obj = "Hello";
Integer num = (Integer) obj; // 抛出 ClassCastException检查异常(Checked Exception)
java
// IOException
try {
FileInputStream fis = new FileInputStream("file.txt");
} catch (IOException e) {
System.out.println("IO 异常: " + e.getMessage());
}
// SQLException
try {
Connection conn = DriverManager.getConnection(url);
} catch (SQLException e) {
System.out.println("数据库异常: " + e.getMessage());
}异常处理最佳实践
1. 捕获具体异常
java
// ✅ 好的做法:捕获具体异常
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("算术异常: " + e.getMessage());
}
// ❌ 不好的做法:捕获所有异常
try {
int result = 10 / 0;
} catch (Exception e) {
System.out.println("异常: " + e.getMessage());
}2. 不要忽略异常
java
// ❌ 不好的做法:忽略异常
try {
processFile();
} catch (IOException e) {
// 什么都不做
}
// ✅ 好的做法:至少记录日志
try {
processFile();
} catch (IOException e) {
System.err.println("处理文件失败: " + e.getMessage());
e.printStackTrace();
}3. 使用 finally 清理资源
java
// ✅ 好的做法:使用 finally 清理资源
FileInputStream fis = null;
try {
fis = new FileInputStream("file.txt");
// 使用资源
} catch (IOException e) {
System.out.println("IO 异常: " + e.getMessage());
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
System.out.println("关闭文件失败: " + e.getMessage());
}
}
}4. 使用 try-with-resources
java
// ✅ 更好的做法:使用 try-with-resources
try (FileInputStream fis = new FileInputStream("file.txt")) {
// 使用资源
} catch (IOException e) {
System.out.println("IO 异常: " + e.getMessage());
}
// 资源自动关闭完整示例
java
public class ExceptionExample {
// 方法抛出异常
public static void divide(int a, int b) throws ArithmeticException {
if (b == 0) {
throw new ArithmeticException("除数不能为0");
}
int result = a / b;
System.out.println("结果: " + result);
}
// 读取文件
public static void readFile(String filename) throws IOException {
FileInputStream fis = new FileInputStream(filename);
int data;
while ((data = fis.read()) != -1) {
System.out.print((char) data);
}
fis.close();
}
// 验证年龄
public static void validateAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("年龄必须在 0-150 之间");
}
System.out.println("年龄有效: " + age);
}
public static void main(String[] args) {
// 处理算术异常
try {
divide(10, 0);
} catch (ArithmeticException e) {
System.out.println("捕获异常: " + e.getMessage());
}
// 处理 IO 异常
try {
readFile("file.txt");
} catch (IOException e) {
System.out.println("文件读取失败: " + e.getMessage());
}
// 处理参数异常
try {
validateAge(-1);
} catch (IllegalArgumentException e) {
System.out.println("验证失败: " + e.getMessage());
}
// 使用 try-with-resources
try (FileInputStream fis = new FileInputStream("file.txt")) {
int data = fis.read();
System.out.println("读取数据: " + data);
} catch (IOException e) {
System.out.println("IO 异常: " + e.getMessage());
}
}
}下一步
掌握了异常处理后,可以继续学习:
💡 提示:良好的异常处理可以提高程序的健壮性,正确处理异常是编写高质量代码的重要部分
