Skip to content

自定义异常

Java 自带的异常够用吗?大多数时候够。但当你需要表达业务含义时,自定义异常就派上用场了。

异常继承体系

异常类型特点
Exception受检异常,需处理
RuntimeException非受检异常

基本自定义异常

java
public class CustomExceptionDemo {

    // 继承 Exception(受检异常)
    static class UserNotFoundException extends Exception {
        public UserNotFoundException(String message) {
            super(message);
        }
    }

    // 继承 RuntimeException(非受检异常)
    static class InvalidArgumentException extends RuntimeException {
        public InvalidArgumentException(String message) {
            super(message);
        }
    }

    // 使用
    static User getUser(Long id) throws UserNotFoundException {
        if (id == null) {
            throw new UserNotFoundException("用户不存在");
        }
        return new User(id);
    }
}

带错误码的异常

有时候业务需要错误码,方便前端做判断:

java
public class ErrorCodeException extends RuntimeException {

    private final int errorCode;

    public ErrorCodeException(int errorCode, String message) {
        super(message);
        this.errorCode = errorCode;
    }

    public int getErrorCode() {
        return errorCode;
    }

    public static void main(String[] args) {
        try {
            throw new ErrorCodeException(1001, "参数错误");
        } catch (ErrorCodeException e) {
            System.out.println("错误码: " + e.getErrorCode());
            System.out.println("错误信息: " + e.getMessage());
        }
    }
}

异常链

底层异常发生时,包装成业务异常,同时保留原始异常信息:

java
public class ExceptionChainDemo {

    static class BusinessException extends RuntimeException {
        public BusinessException(String message, Throwable cause) {
            super(message, cause);
        }
    }

    public static void main(String[] args) {
        try {
            // 底层异常
            throw new NullPointerException("原始错误");
        } catch (NullPointerException e) {
            // 包装成业务异常
            throw new BusinessException("业务处理失败", e);
        }
    }
}

这样做的好处是:上层能看到完整的异常链路,排查问题时不会一头雾水。

命名规范

自定义异常命名以 Exception 结尾,让代码阅读者一眼就知道这是个异常类:

java
// 好命名
class UserNotFoundException extends Exception {}
class BusinessException extends RuntimeException {}

// 差命名
class UserNotFound extends Exception {}
class BusinessError extends RuntimeException {}

基于 VitePress 构建