一、Java异常分成俩类:
1. 检查型异常(Checked Exception):编译器强制要求程序员进⾏捕获处理的异常,如 IOException 、 SQLException 等。
2. ⾮检查型异常(Unchecked Exception):编译器不要求强制捕获的异常,如 RuntimeException 及其⼦类。
可查异常,⾮运⾏时异常(编译时异常或已检查异常,必须要在⽅法⾥⾯捕获或者抛出)
是那些编译器会检查是否已经被处理的异常。
如果编写了⼀个可能会抛出⾮运⾏时异常的⽅法,必须在⽅法签名中使⽤ throws 关键字来声明这个⽅ 法会抛出这些异常。
调⽤这个⽅法的代码也必须处理这些异常,或者使⽤ throws 关键字再次声明这些⽅法也可能会抛出这 些异常。
常⻅的⾮运⾏时异常包括:
ClassNoFoundException 应⽤程序试图加载类,找不到对应的类
IllegalAccessException 拒绝访问⼀个类的时候
NoSuchFieldExcetion 请求的变量不存在
NoSuchMethodException ⽅法不存在
IOException :当发⽣输⼊/输出错误时抛出。
SQLException :当使⽤JDBC(Java Database Connectivity)与数据库交互时,发⽣SQL错误或数 据库访问错误时抛出。
不可查异常,运⾏时异常(RuntimeException⼦类)
是那些可能在Java虚拟机正常运⾏期间抛出的异常,但是编译器不会检查这类异常是否被处理
如果编写了⼀个可能会抛出运⾏时异常的⽅法,不需要在⽅法签名中使⽤ throws 关键字来声明这个⽅ 法会抛出这些异常
常⻅的运⾏时异常包括:
NullPointerException :当应⽤程序试图在需要对象的地⽅使⽤ null 时抛出。
ClassCastException 强制失败抛出异常
ArrayIndexOutOfBoundsException :当应⽤程序试图访问数组的⾮法索引时抛出。
ArithmeticException :当出现异常的算术运算条件时抛出,例如除以零。
二、异常处理机制
Java提供了五个关键字来处理异常: try 、 catch 、 finally 、 throw 和 throws 。
try:包含可能出现异常的代码块。
catch:⽤于捕获try块中抛出的异常,并处理它。
finally:⽆论try块中的代码是否抛出异常,finally块中的代码都会被执⾏。它常⽤于关闭资源或进 ⾏清理⼯作。
throw:⽤于显式地抛出⼀个异常,需要是 new 异常类。
throw new ExceptionName("异常信息");
throws:⽤于声明⼀个⽅法可能会抛出的异常,但不处理它,即往外抛。
public class Main {
public static void readChar() throws IOException,RemoteException {
int input = System.in.read();
}
}
基本异常处理代码:
try {
// 可能会抛出异常的代码
int result = 10 / 0; // 这⾥会抛出ArithmeticException
} catch (ArithmeticException e) {
// 处理ArithmeticException异常
System.err.println("捕获到除数为0的异常: " + e.getMessage());
} finally {
// ⽆论是否发⽣异常都会执⾏的代码
System.out.println("finally块中的代码被执⾏了");
}
throws⼦句放在⽅法参数列表的右括号之后,⼀个⽅法可以声明抛出多个异常,多个异常之间⽤ 逗号隔开 。
public void divide(int dividend, int divisor) throws ArithmeticException {
if (divisor == 0) {
throw new ArithmeticException("除数不能为0");
}
System.out.println(dividend / divisor);
}
三、Java内置异常体系分类和核心方法讲解
Throwable类
Java.lang软件包中有⼀个java.lang.Throwable类,这个类是java中所有错误和异常的超类。
Throwable类有两个⼦类,Error与 Exception
Error 错误:
代表系统级别的错误,通常是JVM(Java虚拟机)相关的错误,如 OutOfMemoryError (内存溢 出错误)等。 这些错误通常是不可恢复的,并且⼤多数应⽤程序不应该试图去捕获或处理它们。
Exception 异常:
代表程序可能出现的问题,在编程时需要重点关注的。 Exception 类⼜可以分为运⾏时异常( RuntimeException )和⾮运⾏时异常(即编译时异 常或已检查异常)。
Throwable类(定义了⼀些⽤于处理错误和异常的核⼼⽅法)
public String getMessage()
异常的详细信息
try {
throw new Exception("This is a test exception");
} catch (Exception e) {
System.out.println(e.getMessage()); // 输出 "This is a test exception"
}
public Throwable getCause()
异常原因
Exception cause = new Exception("The cause of the problem");
Exception exception = new Exception("A problem occurred", cause);
try {
throw exception;
} catch (Exception e) {
System.out.println(e.getCause().getMessage()); // 输出 "The cause of the problem"
}
public void printStackTrace()
打印错误的堆栈信息,即错误输出流,可以看到错误原因和所在位置
try {
throw new Exception("This is a test exception");
} catch (Exception e) {
e.printStackTrace(); // 输出异常的堆栈跟踪到标准错误流
}
四、异常处理之多重捕获
多重捕获(Multiple Catch)是Java异常处理中的⼀个重要概念,它允许在单个try块后⾯跟随多个catch 块,
捕获不同类型的异常,这种机制使得代码更加清晰和易于管理,特别是在处理多种可能的异常时。
语法
结构:⼀个 try 代码块后⾯可以跟随多个 catch 代码块,每个 catch 代码块⽤于捕获并处理不同 类型的异常。
顺序: catch 代码块的顺序很重要。Java会按照 catch 代码块的顺序进⾏匹配,将更具体的异常 类型放在前⾯
finally块
在 try/catch 后⾯添加 finally 块是可选的,⽆论是否发⽣异常, finally 代码块的代码 总会被执⾏。
finally 块通常⽤于执⾏清理操作,如关闭⽂件或数据库连接。
```
try {
// 尝试执⾏的代码块
} catch (ExceptionType1 e1) {
// 处理ExceptionType1类型的异常的代码块
} catch (ExceptionType2 e2) {
// 处理ExceptionType2类型的异常的代码块
} catch (ExceptionTypeN eN) {
// 处理ExceptionTypeN类型的异常的代码块
}finally{
}
```
四、自定义异常
什么是⾃定义异常?
1. 当前JDK内置的异常不满⾜需求,项⽬会出现特有异常
2.⾃定义异常可以让业务更清晰
如何进⾏⾃定义异常
1.异常都是继承⾃Exception类,所以我们要⾃定义的异常也需要继承这个基类。
2.定义⼀个新的异常类:继承⾃ Exception 或 RuntimeException 。
3.提供构造函数:提供⼀个或多个构造函数,这些构造函数可以接受⼀个描述异常详情的字符串,并传递 给⽗类的构造函数。
4.(可选)添加其他⽅法:根据需要,还可以在⾃定义异常类中添加其他⽅法或字段。
案例:
需求:编写⼀个处理数据的程序,在数据⽆效时抛出⼀个异常,名称叫 InvalidDataException
定义异常类
public class InvalidDataException extends RuntimeException {
// 默认的构造函数
public InvalidDataException() {
super(); // 调⽤⽗类Exception的默认构造函数
}
// 带错误消息的构造函数
public InvalidDataException(String message) {
super(message); // 调⽤⽗类Exception的带消息参数的构造函数
}
// 带错误消息和原因的构造函数
public InvalidDataException(String message, Throwable cause) {
super(message, cause); // 调⽤⽗类Exception的带消息和原因参数的构造函数
}
// (可选)添加其他⽅法或字段
// ...
}
当检测到⽆效数据时,创建⼀个新的 InvalidDataException 实例并抛出它
public class DataProcessor {
public void processData(String data) throws InvalidDataException {
// 假设这⾥有⼀些验证数据的逻辑
if (data == null) {
throw new InvalidDataException("Invalid data: " + data);
}
// 处理有效数据的逻辑...
}
}
调⽤ processData ⽅法的代码中使⽤try-catch块来处理
public class Main {
public static void main(String[] args) {
DataProcessor processor = new DataProcessor();
try {
processor.processData("这个是测试数据");
} catch (InvalidDataException e) {
e.printStackTrace(); // 或者你可以根据⾃⼰的需要处理异常
}
}
}