在Java语言中,异常的继承结构大致是:
Throwable
-- Error
-- -- OutOfMemoryError(OOM)
-- Exception
-- -- IOException
-- -- -- FileNotFoundException
-- -- RuntimeException
-- -- -- NullPointerException(NPE)
-- -- -- IllegalArgumentException
-- -- -- ClassNotFoundException
-- -- -- ClassCastException
-- -- -- ArithmeticException
-- -- -- IndexOutOfBoundsException
-- -- -- -- ArrayIndexOutOfBoundsException
-- -- -- -- StringIndexOutOfBoundsException
如果调用的某个方法抛出了非RuntimeException
,则必须在源代码中使用try...catch
或throws
语法,否则,源代码将报错!而RuntimeException
不会受到这类语法的约束!
在项目中,如果需要通过抛出异常来表示某种“错误”,应该使用自定义的异常类型,否则,可能与框架或其它方法抛出的异常相同,在处理时,会模糊不清(不清楚异常到底是显式的抛出的,还是调用其它方法时由那些方法抛出的)!同时,为了避免抛出异常时有非常多复杂的语法约束,通常,自定义的异常都会是RuntimeException
的子孙类异常。
另外,抛出异常时,应该对出现异常的原因进行描述,所以,在自定义异常类中,应该添加带String message
参数的构造方法,且此构造方法需要调用父类的带String message
参数的构造方法。
则在项目的根包下创建ex.ServiceException
异常类,继承自RuntimeException
,例如:
package cn.tedu.csmall.product.ex;
/**
* 业务异常
*
* @author java@tedu.cn
* @version 0.0.1
*/
public class ServiceException extends RuntimeException {
public ServiceException(String message) {
super(message);
}
}
然后,在Service中,就抛出此类异常,并添加对于错误的描述文本,例如:
if (count != 0) {
// 是:名称已存在,不允许创建,抛出异常
throw new ServiceException("添加相册失败,尝试添加的相册名称已经被占用!");
}
在Controller中,将调用Service中的方法,可以使用try..catch
包裹这段代码,对异常进行捕获并处理,例如:
try {
albumService.addNew(albumAddNewDTO);
return "添加相册成功!";
} catch (ServiceException e) {
return e.getMessage();
}