软件构造 7-2 错误与异常处理

错误与异常处理

目录(机翻不要介意)

1.一般的错误与异常处理方法

2.java中的错误与异常处理

  异常的分类

  检查与不用检查异常

  如何抛出异常

  创建异常类

  捕获异常

  重新抛出和连接异常

  最终的主句(finally)

  Try-with-resources状态

  分析栈轨迹元素

  使用异常的建议

通常的错误与异常

此错误非java上的错误,意味着在编程中所有不正常的事情

错误分类

1.用户输入错误

2.设备错误

3.物理条件限制(内存满了)

4.代码错误

错误处理:编程,应用程序通信中错误的预测,检测和解决

预先防止

错误中恢复

优雅退出

当遇到错误或者操作不能完成时,这个程序应该

1.告诉用户错误

2.保存所有工作

3.回到安全状态允许用户去进行其他命令

4.允许用户保存数据和优雅的退出

处理错误

难点在于检测错误的代码通常余力可以滚回数据或保存数据并优雅退出代码

错误处理任务就是将控制权从发生错误的位置转移到可以处理错误的程序

(1)返回一个中性值。通用值或缺省值,0,null或空指针

  但是对安全和生命相关的程序,就要严格正确

(2)用下一个有效值代替(如略去空格)

(3)返回上一个相同的答案

(4)替换为最近的合法值

(5)文件中记录(使用日志)警告信息

(6)返回错误的代码(设置状态值,返回状态值,利用异常机制)

(7)调用错误进程对象

(8)展示错误信息

(9)局部地处理错误

(10)停止运行(如日志写满时)

错误处理的高级机制

1.整个程序使用一致的处理机制

2.错误处理机制同程序的正确型、健壮性和其他非功能指标密切相关

3.错误处理机制决策是体系结构级别或高层设计决策问题

确定错误机制后要严格执行

防御性编程重点在防范不期望的错误

java中的错误和异常处理

Error类描述的是java虚拟机内部错误,多数情况无需处理,也无法处理(不用抛出)

Exception类描述程序导致的错误,需要处理。

什么是异常

异常处理机制将允许代码将错误或者异常事件传递给调用它的代码

当方法不能正常完成时提供了另外一个退出路径

  a.方法抛出异常,停止执行,不返回任何值,不执行后续代码

  b.异常处理机制捕获异常,寻找到可以处理此异常的代码进行处理

好处:不会忘记处理错误模式,提供对错误和栈追踪高级总结,提高代码结构,使提高健壮性和可维护性更为轻松

使业务逻辑代码与错误处理代码分离

即try中也无逻辑catch再分开处理。不要多个异常一个一个的try-catch

异常分类

继承自Throwable

两大类:1继承自RuntimeException 和2其他

1.因为你造成了程序错误(你的错)

2.因为其他不好的事,比如你输入错误

(1)RuntimeException有

1.不好的类型转换

2.数组越界

3.空指针

等等

(2)其他

1.读取文件末端

2.打开不存在的文件

3.依据一个串(名字)找不存在的类

等等

checked 和unchecked exceptions(检查和不用检查的异常)

不用检查的异常error和runtimeException(数组越界,空指针,强转错误)

使用parseInt但是参数不对

 非法参数

引用失败

其他的必须捕获

 试用try-catch,finally,throws和throw

声明异常用throws

抛出异常用throw

捕捉异常用try,catch,finally

1.如何throws  

在函数开头使用throws声明自己要抛出的异常

在函数满足条件的情况下throw该异常

找到或者设计合适的异常类

创建异常类对象

抛出

一旦方法抛出一个异常,它就不会返回到调用者,者意味着不需要单行会默认返回值或错误编码

创建异常对象

当你的异常没有响应的异常类时

将其继承某一异常类

习惯上给一个默认的构造函数和一个详细的

toString会返回错误的详细信息

捕捉异常

 异常不被捕捉程序就会结束,然后打印栈轨迹最终(哪里有问题)

GUI程序捕捉异常,会打印错误地点然后返回值用户界面循环

使用try-catch模块捕捉异常

当try模块出现异常是,将忽略异常位置之后的代码,有catch字句进行异常处理

无异常时catch不执行

如果catch语句中没有匹配的异常处理,则访问程序退出

将异常给调用者

处理知道如何处理的异常,传递不知道如何处理的异常

传播异常时通过throws通知调用者处理

如果子类重写了父类的方法但是父类方法没有抛出异常,那么子类需要catch所有的checked

子类继承自父类的方法,在子类中不能增加异常

得到异常的详细信息

(e是catch的那个参数)得到详细的错误信息

得到准确的异常类名

用多个catch抓住不同的异常

重新抛出和连接异常

你可以在catch部分抛出一个异常,这样一般用来改变异常类型,对异常信息重新封装

比如这里就对异常进行了进一步的说明。

当然最好是吧原始异常信息传递出去

这种包装技术允许在子系统中抛出高级异常,而不对事原始失去细节。

被重新抛出的异常也要被捕捉。

 finally Clause(最终的主句)

出现问题时需要清理占用的资源

一种方法是catch并且重新抛出所有异常(太麻烦了。。。)

于是finally就出现了

finally部分是否捕捉异常都会被执行

 try部分-》catch部分(可能有,即使中间继续抛出也不影响)-》finally部分-》外部

那么为什么不在try里写呢?因为可能没有到try相应部分就到catch了。或者如果没有catch就不需要那部分操作。

fianlly不一定跟在catch后面,可以单独使用

 try-with-Resources 状态

回收资源的try,在try()中加入限定那么在try结束后括号中的打开的东西也会关闭。里面的res会在try完成时自动调用res.close()

当这里出现异常catch时同样会调用close

分析栈追踪元素

就是你eclipse下每当你出现异常它会告诉你的一长串东西,越前面距离事发地点越近(这些部分正在等待正在执行部分的回应,却何曾想到等到满门抄斩,惨烈)

 异常处理机制:异常被抛出时,JVM根据异常中的信息查找处理异常的代 码,通过调用栈进行反向查找,直到找到为止,如果找不到则终止程序。就是你的异常没有被捕捉。

更为寻常的分析栈中元素的方法是

通过getStackTrace的方法得到栈中元素在分析,toString包含了其中的信息

建议

1.异常处理不能代替简单的测试(必要的时候才使用)

2.不要过分细化异常(将正常处理和异常处理分开,不要到处都try-catch,try一下(不是真的叫你只用一次)catch多次)

3.利用好异常层次结构

  a.不要只抛出异常

  b.不要只捕获throwable异常

  c.考虑已检查与未检查异常的区别

  d.将一种异常装换为另外一种异常时不要犹豫

4.苛刻比放任要好

5.不要羞于传递异常,让高层方法通知用户发生了错误,或者放弃不成功的命令更适宜。

  反正:早抛出,晚捕获“throw early, catch late“

6.不要捕捉不用检查的异常

7.建议复用java预定义的异常

8.根据抽象级别抛出合适的异常 ,高层应该捕获低层的异常,并抛出在高层抽象可以理解的异常 

9.document为每个抛出的异常

猜你喜欢

转载自www.cnblogs.com/hitycy/p/10882083.html
7-2
今日推荐