前提
之前的一篇文章曾讲解了Java的异常处理机制,这篇文章主要讲解java中异常类,以及异常体系。
异常体系
当Java运行的时候接收到异常对象后,会根据java异常类的继承体系,根据catch中关键字,寻找异常类或子类的实例。异常类的体系如图
Error错误
一般都和虚拟机有关系,系统崩溃,虚拟机错误,动态链接失败等,一般这种错误无法恢复或不可能捕获,导致程序中断。因为这些错误一般程序无法处理,所以不应该视图用catch捕获Error错误。
Java中异常又分为两大类,Checked异常和Runtime异常,所有RuntimeException类和子类的实例都是Runtime异常,其余的异常被称为Checked异常。而且只有Java中存在Checked异常,java认为Checked错误都是可以被修复的,所以必须显示处理Checked错误,否则无法编译通过。
关于Checked错误两种处理方案
1、明确知道如何处理该异常,程序通过try...catch 捕获,在catch中修复异常
2、不知道当前方法如何处理该异常的,定义该方法是声明抛出异常。
关于声明抛出异常两种方案
1、使用throws声明异常
使用throws当前方法不知道如何处理该异常,则该异常有上层调用者处理,throws声明抛出只能在方法签名中使用,但是可以throws可以抛出多个异常类,多个异常类用逗号分隔开。当使用throws同样受到继承机制的限定,子类中声明的异常需要比父类中声明的异常类型相同或者为其子类。
public boolean insertQuestionMainAndSub(List<QuestionParentMainSubModel> questionParentMainSubModelList) throws IOException,SQLException
2、使用throw抛出异常
若需要在程序中自行抛出异常,则该使用throw语句,throw可以单独使用,而且throw抛出的是一个异常实例
throw new ItooRuntimeException(e);
自定义异常类
通常程序很少自行抛出异常,因为异常的类名一般都包含了异常的有用信息,所以在抛出异常的时候需要选择合适的异常类,进而准确的描述该异常的一些问题。
用户自定义的异常类都需要继承Exception基类,如果希望是Runtime异常,则继承RuntimeException基类。一般自定义异常类提供两个构造函数,一个是无参数,另一个是带字符串参数的构造器,这个字符串将作为该异常对象的描述,根据准确描述异常的信息。
import java.io.Serializable;
public class ItooRuntimeException extends RuntimeException implements Serializable {
public ItooRuntimeException() {
}
public ItooRuntimeException(String message) {
super(message);
}
public ItooRuntimeException(String message, Throwable cause) {
super(message, cause);
}
public ItooRuntimeException(Throwable cause) {
super(cause);
}
}
catch和throw同时使用
当程序发生异常,使用catch拦截真正的错误原因,使用throw将该异常转为根据清晰明确的信息反馈,不仅仅可以提高程序修复的速度同时可以提高用户的易用性。
public boolean insertQuestionMainAndSub(List<QuestionParentMainSubModel> questionParentMainSubModelList) {
try {
return questionBankManagerService.insertQuestionMainAndSub(questionParentMainSubModelList);
} catch (Exception e) {
logger.error("插入试卷题干和选项时发生错误!", e);
throw new ItooRuntimeException("错误插入题干错误");
}
}
异常链
在企业级应用中,有严格的分层机制,每层之后都存在严格的依赖关系,例如dao层出现了异常,但是我们不想让用户看到,则可以使用catch+throw的方式,将错误信息封装,实现异常转译。
是否可以使用异常替代正常的流程控制?
答案是可以,但是不建议,理由:异常处理机制的初衷为了将不可预期异常的处理代码和正常的业务逻辑代码分离,因此不建议使用异常处理来代替正常的业务判断,而且使用异常效率比正常的流程控制效率差。
总结
使用好异常处理,能在极大程度上帮助提高程序的开发效率,同时异常处理也杜绝滥用,例如使用过于庞大的try语句块,业务过于复杂,会导致分析异常处理的难度增加。最重要的是不要忽略别catch的异常,根据实际情况妥善处理的异常,否则程序发生错误将会很难发现,加大开发的困难,同时在有事务的方法中更加主要异常的处理,根据业务判断catch异常,还是throw让事务回滚,还是需要在实践中多多锻炼!
上述内容个人项目中经验,如有理解偏颇之处,还请各位大神指出,小编不胜感激!