Java中的异常捕获
1. 异常捕获的方式
try-catch-finally
- try 块负责监控可能出现异常的代码
- catch 块负责捕获可能出现的异常,并进行处理
- finally 块负责清理各种资源,不管是否出现异常都会执行
说明:其中 try 块是必须的,catch 和 finally 至少存在一个标准异常处理流程
2. 异常代码执行时机
关于try-catch-finally中执行情况的说明
1. 正常情况(try)
如果 try 块中的代码正常执行到 return 语句
- 首先,计算 return 语句的值
- 然后,控制权转移到 finally 块(有finally)。注意,此时 return 语句的值已经被计算但尚未返回给调用者。
- finally 块执行完毕后,如果 finally 块中没有 return、throw 或 System.exit() 等导致方法立即终止的语句,则执行原始 try 块中的 return 语句,将值返回给调用者。
2. 异常情况(catch)
如果 try 块中的代码抛出了异常,并且这个异常被 catch 块捕获。
- 执行 catch 块中的代码。
- 如果 catch 块中包含 return 语句,则首先计算 return 语句的值(有return)。
- 然后,控制权转移到 finally 块(有finally)。同样,此时 return 语句的值已经被计算但尚未返回给调用者。
- finally 块执行完毕后,如果 finally 块中没有 return、throw 或 System.exit() 等导致方法立即终止的语句,则执行 catch 块中的 return 语句,将值返回给调用者。
3. finally
如果 finally 块中也包含 return 语句。
- 无论 try 或 catch 块中是否执行了 return 语句,finally 块中的 return 语句都将覆盖它们。
- 方法始终返回 finally 块中 return 语句的值(如果有的话)。
3. 自定义异常
自定义异常的使用
- 在开发过程中会使用到自定义异常。
- 因为异常的类名通常也包含了该异常的有用信息,所以在选择抛出异常的时候,应该选择合适的异常类,从而可以明确地描述该异常情况,所以这时候往往都是自定义异常。
- 自定义异常通常是通过继承 java.lang.Exception 类,如果想自定义 Runtime 异常的话,可以继承
java.lang.RuntimeException 类,实现一个无参构造和一个带字符串参数的有参构造方法。
3.1 自定义异常类
public class MyException extends Exception{
// 构造函数,仅带消息
public MyException(String message) {
super(message);
}
// 构造函数,带消息和原因
public MyException(String message, Throwable cause) {
super(message, cause);
}
// 构造函数,仅带原因
public MyException(Throwable cause) {
super(cause);
}
}
3.2 使用自定义异常
public class TestException {
public static void main(String[] args) {
Throwable exception = new Exception("底层异常");
try {
throw new MyException("上层异常",exception);
} catch (MyException e) {
e.printStackTrace();
}
}
}