1.为什么要使用自定义异常,有什么好处?

1.隐藏底层异常,统一对外异常展示方式

我们在工作的时候,项目是分模块或者分功能开发的 ,基本不会你一个人开发一整个项目,使用自定义异常类就统一了对外异常展示的方式。

使用自定义异常继承相关的异常来抛出处理后的异常信息可以隐藏底层的异常,这样更安全,异常信息也更加的直观。自定义异常可以抛出我们自己想要抛出的信息,可以通过抛出的信息区分异常发生的位置,根据异常名我们就可以知道哪里有异常,根据异常提示信息进行程序修改。比如空指针异常NullPointException,我们可以抛出信息为“xxx为空”定位异常位置,而不用输出堆栈信息。

2.结束当前请求(或方法)

有时候我们遇到某些校验或者问题时,需要直接结束掉当前的请求,这时便可以通过抛出自定义异常来结束,如果你项目中使用了SpringMVC比较新的版本的话有控制器增强,可以通过 @ControllerAdvice注解写一个控制器增强类来拦截自定义的异常并响应给前端相应的信息。

3.自定义符合业务需求的异常

自定义异常可以在我们项目中某些特殊的业务逻辑时抛出异常,比如"中性".equals(sex),性别等于中性时我们要抛出异常,而Java是不会有这种异常的。系统中有些错误是符合Java语法的,但不符合我们项目的业务逻辑。

2.自定义异常有什么不好或不足的地方

JVM(Java虚拟机)无法处理自定义异常(我们不可能期待JVM自动抛出或自动处理一个自定义异常),发现、抛出以及处理异常,需要编程人员使用异常处理机制自己完成,增加了一些开发成本和工作量。如何使用自定义异常,需要开发者自己去权衡。

3.如何使用自定义异常

在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。

  • 所有异常都必须是 Throwable 的子类。
  • 如果希望写一个检查性异常类,则需要继承 Exception 类。
  • 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。

可以像下面这样定义自己的异常类:

class MyException extends Exception{ }

 

我们来看一个完整的实例:

package cn.myjava.util;

/**
 * 自定义异常
 */
public class MyRuntimeException extends RuntimeException {

    //异常Code
    private String errorCode;

    public MyRuntimeException() {
        super();
    }

    public MyRuntimeException(String message) {
        super(message);
    }

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

    public MyRuntimeException(String message, Throwable cause) {
        super(message, cause);
    }

    public MyRuntimeException(String errorCode, String message, Throwable cause) {
        super(message, cause);
        this.errorCode = errorCode;
    }

    public MyRuntimeException(Throwable cause) {
        super(cause);
    }

    protected MyRuntimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }
}

使用自定义异常抛出异常信息

public class CustomException {

    public static void main(String[] args) {
        Map<String, Object> dataMap = new HashMap<>();
        String data = null;
        try {
            data = dataMap.get("name").toString();
        } catch (NullPointerException e) {
            throw new MyRuntimeException("0", "名称不能为空");
        }

    }

}

结果:

Exception in thread "main" cn.myjava.util.MyRuntimeException: 名称不能为空
     at cn.myjava.knowledge.CustomException.main(CustomException.java:21)