记录一些小知识点:
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 通过异常增强返回给客户端统一格式 ,这个还没研究,先附个链接。