java使用枚举类实现自定义异常

时间:2022-12-02 20:30:10

记录一些小知识点:

  1、java异常根本父类为Throwable, Throwable有两个子类:Error和Exception。

  2、Exception常见的子类有:

    DataFormatException, IOException, NoSuchFieldException, RuntimeException, SQLException, TimeoutException。

  3、RuntimeException常见的子类有:

    BufferOverflowException, ClassCastException, IndexOutOfBoundsException,NullPointerException, SystemException。

  4、Error不需要讨论,这些错误是正常编码不会出现或者在程序层面无法处理的事情。

  5、Error和RuntimeException是非检查型异常,其他的都是检查型异常。

    检查型异常,顾名思义,编辑器会帮助你检查,如果你编码错误,编辑器会报红,如果可能出现此种异常,必须要用try-catch包裹住。

    运行时异常,不需要使用try-catch包裹,编码编译可以通过。

  6、另说个小坑:如果在更新服务器时,忘记了更新某些文件导致方法找不到的异常,好像是抛出了error的一个子类,反正exception没有捕获到,日志里也没有任何体现,很坑。

现在开始编写自定义异常

  1、枚举类

/**
 * 异常模板,ecode可以作为统一的应答码
 * @author C
 * @date 2018年12月12日 上午10:10:42
 */
public enum CExceptionEnums {    
    SERVER_DO_ERROR                ("0001","交易处理失败"),    
    SERVER_FTP_DOWN_ERROR        ("0002","从ftp下载文件失败"),
    SERVER_ALIYUN_UPLOAD_ERROR    ("0003","上传阿里云失败"),
    SERVER_IMG_ERROR            ("0004","图片错误"),
    SERVER_DB_ERROR                ("0005","数据库错误"),
    SERVER_OTHER_ERROR            ("1099","其他异常");//枚举类如果写方法的话,此处需要写分号

    private String ecode;

    private String emsg;

    CExceptionEnums(String ecode, String emsg) {
        this.ecode = ecode;
        this.emsg = emsg;
    }

    public String getEcode() {
        return ecode;
    }

    public String getEmsg() {
        return emsg;
    }

    public static CExceptionEnums statOf(String ecode) {
        for (CExceptionEnums state : values())
            if (state.getEcode().equals(ecode))
                return state;
        return null;
    }
}

  2、自定义异常

/**
 * 自定义异常
 * @author C
 * @date 2018年12月12日 上午10:09:15
 */
public class CException extends Exception implements java.io.Serializable {
    private static final long serialVersionUID = 1L;
    /*
     * 模版异常
     */
    private CExceptionEnums exceptionEnums;
    /*
     * 自定义异常信息
     */
    private String errorDetail;
    
    /**
     * 带自定义异常信息的构造方法
     * @param exceptionEnums
     * @param errorDetail
     */
    public CException(CExceptionEnums exceptionEnums,String errorDetail){ 
        this.exceptionEnums = exceptionEnums; 
        this.errorDetail = errorDetail;
    }
    
    /**
     * 模版异常的构造方法
     * @param exceptionEnums
     */
    public CException(CExceptionEnums exceptionEnums){ 
        this.exceptionEnums = exceptionEnums; 
    }
    
    public CExceptionEnums getExceptionEnums() {
        return exceptionEnums;
    }

    public String getErrorDetail() {
        return errorDetail;
    }

    public void setErrorDetail(String errorDetail) {
        this.errorDetail = errorDetail;
    }
}

  3、使用方法

/**
 * 
 * @author C
 * @date 2018年12月12日 上午10:11:35
 */
public class exceptionTest {
    
    public static void main(String[] args) {
        try{            
            //自己方法内部的异常可以统一用exception捕获,在catch中再抛出CxzException,在上一层方法里用CxzException捕获
            //自定义异常用法示例            
            if(true){
                //可以使用模版异常
                throw new CException(CExceptionEnums.SERVER_DO_ERROR);                
            }
            if(false){
                //也可以自定义msg信息
                throw new CException(CExceptionEnums.SERVER_DO_ERROR,"自定义msg信息");
            }
            
            dbfunc();
            
        }catch(CException ex){
            //捕获自定义异常
            ex.printStackTrace();
            System.out.println(ex.toString());
            CExceptionEnums enums = ex.getExceptionEnums(); 
            //此处逻辑,若无自定义信息,则使用默认enums中的msg,如有,则使用自定义异常信息
            if (null != ex.getErrorDetail()){
                //如果自定义信息不是null,就使用自定义信息
                String cmsg = ex.getErrorDetail();
            }
            
        }catch(Exception ex){
            
        }
    }
    
    /**
     * 假设这是个与数据库有关的方法
     * 方法内抛异常可以用Exception捕获,再抛出CxzException,上级去处理
     * @throws CException 
     */
    private static void dbfunc() throws CException{
        try{
            if(true){
                throw new Exception("数据库异常信息");
            }
        }catch(Exception ex){
            System.out.println(ex.getMessage());//打印日志--异常中可能有数据库表或字段的名字,不对外暴露
            throw new CException(CExceptionEnums.SERVER_DB_ERROR);//对外不暴露数据库信息,只显示模版异常
        }
    }
}

  这样,自己的项目就可以对外有一个统一的应答码(比如你是一个对外提供接口的程序或者对前台的响应),报错信息也由自己编写,对外不暴露项目的一些东西。

另:

  在springMvc中,    springmvc 通过异常增强返回给客户端统一格式  ,这个还没研究,先附个链接。