記錄一些小知識點:
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 通過異常增強返回給客戶端統一格式 ,這個還沒研究,先附個鏈接。