java 异常指的是破坏原来正常程序运行指令的事件,分三种:
checkedExceptionruntime exceptionErrorcheckedException 受检测异常是一中预期的能够恢复的 ,比如:文件类型 打印机没纸了。这些我们可以事先处理这种情况并提醒客户,客户可以重新选择文件和加纸张就可以恢复了
runtime exception运行时异常,程序内部的错误的逻辑或者错误的使用API,一般是不可预期和恢复的,比如:空指针,数组越界等异常
Error 程序外包引起,比如内存,io等硬件,比如:内存异常 ,IOException
Error 可以看作是虚拟机错误 ,runtime exception运行时异样看作是应用的错误 ,checkedException 受检测异常看作是操作错误
异常使用过程中需要注意的几点
只针对异常的情况才使用异常对可恢复的异常使用检测异常 ,对于编程错误使用运行异常避免不必要地使用受检的异常优先使用标准的异常抛出与抽象相对应的异常每个方法抛出的异常都要有文档在细节消息中包含能捕获失败的信息努力使失败保持原子性只针对异常的情况才使用异常,如:
//糟糕的代码示例try{int i = 0;while(true)range[i++].climb();}catch(){}//标准模式for(Mountain m:range)m.climb();有开发者可能认为遍历会进行检测,为了提供效率故而采用第一种代码方式,有三种错误 1.不符合异常机制设置的初衷 2.把代码放在try-catch块中 可能会阻止现代jvm本来可能会执行的优化 3.遍历不会执行多余的检测,已经执行优化
对可恢复的异常使用检测异常 ,对于编程错误使用运行异常 如果期望调用的能够适当的恢复,对于这种情况使用检测异样
避免不必要地使用受检的异常 异常虽然能增加代码的可靠性,但也会增加不方便,如果方法抛出一个或多个受检测异常,那么调用方法就需要多个catch来处理这些,也算是一中负担,如果一个方法只抛出单一的异常,可以考虑避免使用受检异常。比如用if 检测一下条件
优先使用标准的异常,api自带一些常用的异常,我们可以复用这些异常,减少类的加载。
抛出与抽象相对应的异常,如果方法返回与处理业务无关的异常,这种情况将会使人不知所措,如果方法直接传递了低层的异常,不仅使人困惑,而且污染了高层API,为了避免这个问题,需要进行异常转译
//异常转译try{...//低层异常}catch(LowerException e){throw new HigherException();}每个方法抛出的异常都要有文档, 是指方法抛出的异常需要注明什么情况会出现这种异常
在细节消息中包含能捕获失败的信息,包含能够所有“对异常有贡献的”参数和域的值,方便后续解决问题,这里的细节消息需要和用户消息区分,细节消息是为了分析失败原因
努力使失败保持原子性,产生的任何异样都应该让对象保持在该方法调用之前的状态,比如下面代码 ,如果去掉检测size ,试图从一个空栈弹出元素,这时还是会抛出异常,然而,这将导致size域保持不一致负数的状态。导致后面操作失败 ,比如增加等。
public Object pop(){if(size==0){throw new EmptyStackException()}Object result = elements[--size]elements[size]=nullreturn result}新闻热点
疑难解答