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