自定义异常的详细说明
-
命名规范:自定义异常类的名称应当以
Exception
结尾,这样可以一目了然地知道这是一个异常类。例如FileNotFoundException
、InvalidUserInputException
等。 -
提供多种构造方法:为了灵活性,建议自定义异常类提供多种构造方法,包括:
- 默认构造方法
- 带错误信息的构造方法
- 带错误信息和原因的构造方法
- 带原因的构造方法
-
添加序列化支持:如果异常类需要序列化(例如在分布式系统中传递异常),请实现
Serializable
接口并提供serialVersionUID
。 -
封装额外信息:有时需要在异常中传递更多的信息,例如错误代码。可以在自定义异常类中添加额外的字段和方法。
-
记录日志:在捕获自定义异常时,建议记录日志以便于后续分析和调试。
完整的例子
定义自定义异常类
// 自定义受检异常类
public class MyCheckedException extends Exception {
private static final long serialVersionUID = 1L;
private int errorCode;
// 默认构造方法
public MyCheckedException() {
super();
}
// 带错误信息的构造方法
public MyCheckedException(String message) {
super(message);
}
// 带错误信息和原因的构造方法
public MyCheckedException(String message, Throwable cause) {
super(message, cause);
}
// 带原因的构造方法
public MyCheckedException(Throwable cause) {
super(cause);
}
// 带错误信息和错误代码的构造方法
public MyCheckedException(String message, int errorCode) {
super(message);
this.errorCode = errorCode;
}
// 获取错误代码
public int getErrorCode() {
return errorCode;
}
}
使用自定义异常
public class MyService {
public void performAction() throws MyCheckedException {
// 业务逻辑
boolean errorOccurred = true; // 模拟错误情况
if (errorOccurred) {
throw new MyCheckedException("Something went wrong in performAction", 1001);
}
}
}
捕获和处理自定义异常
import java.util.logging.Logger;
public class MyApplication {
private static final Logger logger = Logger.getLogger(MyApplication.class.getName());
public static void main(String[] args) {
MyService service = new MyService();
try {
service.performAction();
} catch (MyCheckedException e) {
logger.severe("Caught MyCheckedException: " + e.getMessage() + " with error code: " + e.getErrorCode());
e.printStackTrace();
}
}
}
运行结果
当运行上述代码时,程序会模拟一个错误情况并抛出自定义异常 MyCheckedException
。捕获该异常后,日志会记录错误信息和错误代码,并打印堆栈跟踪。
2024-6-5 17:00:00 SEVERE MyApplication: Caught MyCheckedException: Something went wrong in performAction with error code: 1001
MyCheckedException: Something went wrong in performAction
at MyService.performAction(MyService.java:8)
at MyApplication.main(MyApplication.java:10)
解释运行结果
- 时间戳:
2024-6-5 17:00:00
表示日志记录的时间。 - 日志级别:
SEVERE
表示日志级别是严重错误(SEVERE),通常用于记录重大错误或系统崩溃等情况。 - 类和方法:
MyApplication
表示日志记录发生在MyApplication
类中。具体的日志消息是Caught MyCheckedException: Something went wrong in performAction with error code: 1001
,表示捕获到了MyCheckedException
异常,并记录了异常消息和错误码1001
。 - 异常类型:
MyCheckedException
表示抛出的异常类型。 - 异常消息:
Something went wrong in performAction
表示异常的具体错误消息。 - 异常栈轨迹:
at MyService.performAction(MyService.java:8)
表示异常发生在MyService
类的performAction
方法中,具体位置在MyService.java
文件的第 8 行。at MyApplication.main(MyApplication.java:10)
表示main
方法调用了performAction
方法,具体位置在MyApplication.java
文件的第 10 行。
代码触发异常的过程
- 调用
performAction
方法:在main
方法中,创建了MyService
的实例,并调用了performAction
方法。 - 抛出异常:
performAction
方法模拟了一个错误,并抛出了MyCheckedException
异常,错误消息为 "Something went wrong in performAction",错误码为1001
。 - 捕获异常:在
main
方法中,使用try-catch
块捕获了MyCheckedException
异常。 - 记录日志:捕获异常后,使用
logger.severe
方法记录了严重级别的日志,包含异常消息和错误码。 - 打印栈轨迹:使用
e.printStackTrace()
打印了异常的栈轨迹,帮助定位异常发生的位置。
代码中的关键点
- 自定义异常类
MyCheckedException
:继承自Exception
,并包含一个错误码属性。 - 业务逻辑类
MyService
:包含一个performAction
方法,模拟错误并抛出自定义异常。 - 主函数
main
:调用performAction
方法,并捕获和处理自定义异常,记录日志并打印栈轨迹。