引言:
- Java中的异常处理是保证程序健壮性(Robustness)的核心机制。简单来说,异常就是程序在运行过程中出现的“意外情况”,如果不妥善处理,程序就会直接崩溃。
异常体系
- Java的异常体系是基于层级结构的,所有的异常都继承自java.lang.Throwable类。
异常类的层次结构
Throwable (根类,所有异常和错误的超类)
├─ Error (错误):JVM系统级错误,程序无法处理,比如内存溢出
└─ Exception (异常):程序可以捕获并处理的异常
├─ Checked Exception (受检异常):编译时必须处理(捕获/声明抛出)
└─ Unchecked Exception (非受检异常):RuntimeException及其子类,编译时不强制处理
异常类的具体分类和常用类型
- Error(错误)--- 无需程序处理
- 这类是JVM自身的严重错误,程序只能终止,常见的有:
- OutOfMemoryError:内存溢出错误
- StackOverflowError:栈溢出错误
- NoClassDefFoundError:类定义找不到错误
- Checked Exception(受检异常)--- 编译时强制处理
- 必须通过try-catch捕获,或在方法上用 throws 声明抛出,否则编译报错。常见的有:
- IOException:I/O 操作异常(文件读写、网络传输)
- FileNotFoundException:文件找不到异常(IOException 的子类)
- SQLException:数据库操作异常
- ClassNotFoundException:类加载时找不到指定类
- InterruptedException:线程被中断异常
- Unchecked Exception(非受检异常)- 编译时不强制处理
- 继承自RuntimeException,通常是程序逻辑错误导致,可处理也可不处理。常见的有:
- NullPointerException(NPE):空指针异常(调用 null 对象的方法 / 属性)
- ArrayIndexOutOfBoundsException:数组下标越界异常
- ClassCastException:类型转换异常(比如把 String 强转成 Integer)
- ArithmeticException:算术异常(比如整数除以 0)
- IllegalArgumentException:非法参数异常
- IndexOutOfBoundsException:集合/字符串下标越界(ArrayList、String 的常用异常)
常见异常的触发和处理
- Java提供了五个关键字来处理异常:try、catch、finally、throw、throws。
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class ExceptionDemo {
public static void main(String[] args) {
try {
//捕获异常 (try-catch-finally),这是最常用的方式,将可能出错的代码包裹起来。
// 可能会抛出异常的代码
int result = 10 / 0;
} catch (ArithmeticException e) {
// 捕获特定类型的异常并处理
System.out.println("捕获到除以零异常: " + e.getMessage());
} finally {
// 无论是否发生异常,都会执行的代码块
// 通常用于关闭资源(流、数据库连接等)
System.out.println("资源已清理");
}
// 1. 非受检异常(RuntimeException)- 空指针
String str = null;
try {
System.out.println(str.length()); // 触发NullPointerException
} catch (NullPointerException e) {
System.out.println("捕获空指针异常:" + e.getMessage());
}
// 2. 非受检异常 - 算术异常
try {
int a = 10 / 0; // 触发ArithmeticException
} catch (ArithmeticException e) {
System.out.println("捕获算术异常:" + e.getMessage());
}
// 3. 受检异常(IOException)- 必须处理
File file = new File("test.txt");
try (FileReader fr = new FileReader(file)) {
// 读取文件
} catch (IOException e) { // 捕获FileNotFoundException(子类)和IOException
System.out.println("捕获IO异常:" + e.getMessage());
}
}
}
自定义异常类
- 如果 Java 内置的异常类无法满足业务需求,你可以自定义异常。
// 自定义受检异常(继承Exception)
class MyCheckedException extends Exception {
public MyCheckedException(String message) {
super(message); // 调用父类构造方法
}
}
// 自定义非受检异常(继承RuntimeException)
class MyUncheckedException extends RuntimeException {
public MyUncheckedException(String message) {
super(message);
}
}
// 使用自定义异常
public class CustomExceptionDemo {
public static void main(String[] args) throws MyCheckedException {
// 抛出自定义受检异常(必须声明throws或捕获)
throw new MyCheckedException("自定义受检异常");
// 抛出自定义非受检异常(无需声明)
// throw new MyUncheckedException("自定义非受检异常");
}
}