signed

QiShunwang

“诚信为本、客户至上”

java自定义异常,你需要了解的几个地方

2020/8/20 14:49:29   来源:

1.了解异常

在这里插入图片描述
1.Throwable是从Object直接继承而来(这是Java系统所强制要求的),是Error和Exception的父类,是所有异常对象的根基类,用来定义所有可以作为异常被抛出来的类。

2.Error和Exception区分:
Error(错误)是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防
Exception(异常)表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行

Error是一种严重的问题,应用程序不应该捕捉它。 Exception一般可能是程序和业务上的错误,是可以恢复的。

	```java
	Exception
	│
	├─ RuntimeException
	│  │
	│  ├─ NullPointerException
	│  │
	│  ├─ IndexOutOfBoundsException
	│  │
	│  ├─ SecurityException
	│  │
	│  └─ IllegalArgumentException
	│     │
	│     └─ NumberFormatException
	│
	├─ IOException
	│  │
	│  ├─ UnsupportedCharsetException
	│  │
	│  ├─ FileNotFoundException
	│  │
	│  └─ SocketException
	│
	├─ ParseException
	│
	├─ GeneralSecurityException
	│
	├─ SQLException
	│
	└─ TimeoutException
	```

3.Exception又分为RunTimeException和其他Exception。
RunTimeException和其他Exception区分:
其他Exception,受检查异常。可以理解为错误,必须要开发者解决以后才能编译通过,解决的方法有两种,1:用throws字句声明抛出,交给它的父类处理 2,try-catch捕获处理。
RunTimeException:运行时异常,又称不受检查异常,因为不受检查,所以在代码中可能有RunTimeException的时候,Java编译检查时不会告诉你有这个异常,但是在实际运行代码时则会暴露出来,比如典型的1/0,空指针等。
一些主要子类对应的异常处理功能简要说明如下:

ArithmeticException——由于除数为0引起的异常; 
ArrayStoreException——由于数组存储空间不够引起的异常; 
ClassCastException—一当把一个对象归为某个类,但实际上此对象并不是由这个类 创建的,也不是其子类创建的,则会引起异常; 
IllegalMonitorStateException——监控器状态出错引起的异常; 
NegativeArraySizeException—一数组长度是负数,则产生异常; 
NullPointerException—一程序试图访问一个空的数组中的元素或访问空的对象中的 方法或变量时产生异常; 
OutofMemoryException——用new语句创建对象时,如系统无法为其分配内存空 间则产生异常; 
SecurityException——由于访问了不应访问的指针,使安全性出问题而引起异常; 
IndexOutOfBoundsExcention——由于数组下标越界或字符串访问越界引起异常; 
IOException——由于文件未找到、未打开或者I/O操作不能进行而引起异常; 
ClassNotFoundException——未找到指定名字的类或接口引起异常; 
CloneNotSupportedException——一程序中的一个对象引用Object类的clone方法,但 此对象并没有连接Cloneable接口,从而引起异常; 
InterruptedException—一当一个线程处于等待状态时,另一个线程中断此线程,从 而引起异常,有关线程的内容,将在下一章讲述; 
NoSuchMethodException一所调用的方法未找到,引起异常; 
Illega1AccessExcePtion—一试图访问一个非public方法; 
StringIndexOutOfBoundsException——访问字符串序号越界,引起异常; 
ArrayIdexOutOfBoundsException—一访问数组元素下标越界,引起异常; 
NumberFormatException——字符的UTF代码数据格式有错引起异常; 
IllegalThreadException—一线程调用某个方法而所处状态不适当,引起异常; 
FileNotFoundException——未找到指定文件引起异常; 
EOFException——未完成输入操作即遇文件结束引起异常。

2.自定义异常

在一个稍微大点的项目中,可以自定义新的异常类型,但是,保持一个合理的异常继承体系还是有必要的。
一个常见的做法是自定义一个BaseException作为“根异常”,然后,派生出各种业务类型的异常。
BaseException需要从一个适合的Exception派生,通常建议从RuntimeException派生,spring 对于 RuntimeException 异常才会进行事务回滚。

public class BaseException extends RuntimeException {
}

其他业务类型的异常就可以从BaseException派生:

public class ParamNotFoundException extends BaseException {
}

public class UpdateFailedException extends BaseException {
}
...

自定义的BaseException应该提供多个构造方法,,让派生的异常能够有多的选择

public class BaseException extends RuntimeException {
    public BaseException() {
        super();
    }

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

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

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

另一种方法是用ControllerAdvice,定义一个全局异常处理类,去做全局异常捕捉处理,
如果全部异常处理返回json,那么可以使用 @RestControllerAdvice 代替 @ControllerAdvice ,这样在方法上就可以不需要添加 @ResponseBody。
1.自定义异常

public class MyException extends RuntimeException {
    private int code;
    private String msg;
    public MyException(int code, String msg) {super(msg);this.code = code;this.msg = msg;}
  public MyException(String msg){super(msg);this.msg = msg;}
  public MyException(String msg,Throwable e){super(msg, e);this.msg = msg;}
  public MyException(String msg,int code,Throwable e){super(msg, e);this.msg = msg;this.code = code; }
  public String getMsg(){return msg;}
  public void setMsg(String msg){this.msg = msg;}
  public int getCode(){return code}
  public void setCode(int code){this.code = code;}
}

2.编写全局异常处理类

@ControllerAdvice
public class MyControllerAdvice {
privateLogger logger =LoggerFactory.getLogger(getClass());
    /**
     * 全局异常捕捉处理
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(Exception.class)
    public Map exceptionHandler(Exception ex) {
        logger.error(ex.getMessage(),ex);
        Map map = new HashMap();
        map.put("code", 100);
        map.put("msg", ex.getMessage());
        return map;
    }
    
    /**
     * 拦截捕捉自定义异常 MyException.class
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(MyException.class)
    public Map myExceptionHandler(MyException ex) {
    	logger.error(ex.getMsg(),ex);
        Map map = new HashMap();
        map.put("code", ex.getCode());
        map.put("msg", ex.getMsg());
        return map;
    }
    
	@ExceptionHandler(DuplicateKeyException.class)
	public Map  duplicateKeyExceptionHandle(DuplicateKeyException ex){
	      logger.error(ex.getMessage(), ex);
	       Map map = new HashMap();
	        map.put("code", 105);
	        map.put("msg", "数据库中已存在该记录");
	        return map;
	}