Java异常处理机制及Result最佳实践
-
从jvm层看待异常处理机制
1.当方法抛出异常时,首先会在当前方法的异常表中查找符合的异常处理程序 2.如果找到匹配的异常处理程序,则继续在该异常处理程序中继续执行逻辑 3.如果找不到匹配的,则弹出当前栈帧即结束当前方法的执行,让上一层调用者在其异常表中寻找匹配的异常处理程序....,当在最后一个方法中也找不到匹配的异常处理程序,则终止当前线程 4.如果异常在最后一个非守护线程中被抛出,则jvm会停止。比如这个线程是main线程
注:异常表:可以理解为catch的异常信息
-
业务异常与系统异常
业务异常:用户能看懂的 系统异常:用户看不懂,开发人员能看懂的
案例
- 异常信息枚举类
/** * 异常信息枚举类 */ public enum ErrorCode { /** * 系统异常(开发人员能看懂) */ SYSTEM_ERROR("A000", "系统异常"), /** * 业务异常(用户能看懂的) */ BIZ_ERROR("B000", "业务异常"), /** * 没有权限 */ NO_PERMISSION("B001", "没有权限"), ; /** * 错误码 */ private String code; /** * 错误信息 */ private String message; ErrorCode(String code, String message) { this.code = code; this.message = message; } /** * 获取错误码 * * @return 错误码 */ public String getCode() { return code; } /** * 获取错误信息 * * @return 错误信息 */ public String getMessage() { return message; } /** * 设置错误码 * * @param code 错误码 * @return 返回当前枚举 */ public ErrorCode setCode(String code) { this.code = code; return this; } /** * 设置错误信息 * * @param message 错误信息 * @return 返回当前枚举 */ public ErrorCode setMessage(String message) { this.message = message; return this; } }
- Result 结果类
import java.io.Serializable; /** * Result 结果类 */ public class Result<T> implements Serializable { private static final long serialVersionUID = -1525914055479353120L; /** * 错误码 */ private final String code; /** * 提示信息 */ private final String message; /** * 返回数据 */ private final T data; /** * 是否成功 */ private final Boolean success; /** * 构造方法 * * @param code 错误码 * @param message 提示信息 * @param data 返回的数据 * @param success 是否成功 */ public Result(String code, String message, T data, Boolean success) { this.code = code; this.message = message; this.data = data; this.success = success; } /** * 创建 Result 对象 * * @param code 错误码 * @param message 提示信息 * @param data 返回的数据 * @param success 是否成功 */ public static <T> Result<T> of(String code, String message, T data, Boolean success) { return new Result<>(code, message, data, success); } /** * 成功,没有返回数据 * * @param <T> 范型参数 * @return Result */ public static <T> Result<T> success() { return of("00000", "成功", null, true); } /** * 成功,有返回数据 * * @param data 返回数据 * @param <T> 范型参数 * @return Result */ public static <T> Result<T> success(T data) { return of("00000", "成功", data, true); } /** * 失败,有错误信息 * * @param message 错误信息 * @param <T> 范型参数 * @return Result */ public static <T> Result<T> fail(String message) { return of("10000", message, null, false); } /** * 失败,有错误码和错误信息 * * @param code 错误码 * @param message 错误信息 * @param <T> 范型参数 * @return Result */ public static <T> Result<T> fail(String code, String message) { return of(code, message, null, false); } /** * 获取错误码 * * @return 错误码 */ public String getCode() { return code; } /** * 获取提示信息 * * @return 提示信息 */ public String getMessage() { return message; } /** * 获取数据 * * @return 返回的数据 */ public T getData() { return data; } /** * 获取是否成功 * * @return 是否成功 */ public Boolean getSuccess() { return success; } }
- 系统异常类
package com.abu.stream; /** * 系统异常类 */ public class SystemException extends RuntimeException { private static final long serialVersionUID = 8312907182931723379L; /** * 错误码 */ private String code; /** * 构造一个没有错误信息的 <code>SystemException</code> */ public SystemException() { super(); } /** * 使用指定的 Throwable 和 Throwable.toString() 作为异常信息来构造 SystemException * * @param cause 错误原因, 通过 Throwable.getCause() 方法可以获取传入的 cause信息 */ public SystemException(Throwable cause) { super(cause); } /** * 使用错误信息 message 构造 SystemException * * @param message 错误信息 */ public SystemException(String message) { super(message); } /** * 使用错误码和错误信息构造 SystemException * * @param code 错误码 * @param message 错误信息 */ public SystemException(String code, String message) { super(message); this.code = code; } /** * 使用错误信息和 Throwable 构造 SystemException * * @param message 错误信息 * @param cause 错误原因 */ public SystemException(String message, Throwable cause) { super(message, cause); } /** * @param code 错误码 * @param message 错误信息 * @param cause 错误原因 */ public SystemException(String code, String message, Throwable cause) { super(message, cause); this.code = code; } /** * @param errorCode ErrorCode */ public SystemException(ErrorCode errorCode) { super(errorCode.getMessage()); this.code = errorCode.getCode(); } /** * @param errorCode ErrorCode * @param cause 错误原因 */ public SystemException(ErrorCode errorCode, Throwable cause) { super(errorCode.getMessage(), cause); this.code = errorCode.getCode(); } /** * 获取错误码 * * @return 错误码 */ public String getCode() { return code; } }