错误和异常处理部分的知识总结

因为lab4要用到这部分的内容,所以在这里将这部分的知识进行一个简单的汇总:
首先区分错误和异常:

error:类型有用户输入错误和设备错误,物理限制。对于内部的错误:程序员通常无能为力,一旦发生,想办法让程序优雅的结束。

exception:程序执行中的非正常事件,程序无法再按预想的流程执行。

异常处理:
将错误信息传递给上层调用者,并报告“案发现场”的信息。
return之外的第二种退出途径:若找不到异常处理程序,整个系统完全退出

若将异常按照结构层次分类:有运行时异常(由程序员不当处理造成的,像空指针)和其他异常(程序员无法控制的外在问题导致的)

若异常按处理机制角度的分类:checked exception :编译器可以帮助检查程序是否抛出或处理了可能的异常。异常的向上抛出机制进行处理,如果子类可能产生某种异常,父类也必须抛出某种异常。这样可能导致一个问题就是代码效率低,耦合度过高。

处理机制:抛出:声明是throws,抛出时throw

捕获:(try catch)try出现异常,忽略后续代码直接进入catch,没有异常不进入catch,如果catch没有匹配的异常处理,程序退出;若子类重写了父类方法,父类方法没有抛出异常,子类应该自己处理全部异常不再传播。因为子类从父类继承的方法不能增加或者更改异常。

处理:不能代替简单的测试,将正常处理与异常处理分开,早抛出晚捕获,避免不必要的检查。

清理现场,释放资源(finally):finally中语句不论有无异常都执行。

 

unchecked exception:这类异常都是runtime exception的子类,不能通过client code来试图解决,这类异常不是必须需要catch的,是无法预料的,常见的这类exception有JVM抛出如数组越界数据格式等。

当要决定是采用checked exception还是Unchecked exception的时候,问一个问题: “如果这种异常一旦抛出,client会做怎样的补救?”

如果客户端可以通过其他的方法恢复异常,那么采用checked exception;
如果客户端对出现的这种异常无能为力,那么采用unchecked exception;
异常出现的时候,要做一些试图恢复它的动作而不要仅仅的打印它的信息。
尽量使用unchecked exception来处理编程错误:因为uncheckedexception不用使客户端代码显式的处理它们,它们自己会
在出现的地方挂起程序并打印出异常信息。
如果client端对某种异常无能为力,可以把它转变为一个unchecked exception,程序被挂起并返回客户端异常信息。

 

checked异常的处理机制
【异常中的LSP原则】
如果子类型中override了父类型中的函数,那么子类型中方法抛出的异常不能比父类型抛出的异常类型更广泛
子类型方法可以抛出更具体的异常,也可以不抛出任何异常
如果父类型的方法未抛出异常,那么子类型的方法也不能抛出异常。
其他的参考第五章第二节的LSP
【利用throws进行声明】
使用throws声明异常:此时需要告知你的client需要处理这些异常,如果client没有handler来处理被抛出的checked
exception,程序就终止执行。
程序员必须在方法的spec中明确写清本方法会抛出的所有checked exception,以便于调用该方法的client加以处理
在使用throws时,方法要在定义和spec中明确声明所抛出的全部checked exception,没有抛出checked异常,编译出
错,Unchecked异常和Error可以不用处理。
【利用throw抛出一个异常】
步骤:
找到一个能表达错误的Exception类/或者构造一个新的Exception类
构造Exception类的实例,将错误信息写入
抛出它
一旦抛出异常,方法不会再将控制权返回给调用它的client,因此也无需考虑返回错误代码
【try-catch语句】
使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。

try/catch代码块中的代码称为保护代码,
Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。
如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。
【finally语句】
场景:当异常抛出时,方法中正常执行的代码被终止;但如果异常发生前曾申请过某些资源,那么异常发生后这些资源要被
恰当的清理,所以需要用finally语句。
finally 关键字用来创建在 try 代码块后面执行的代码块。
无论是否发生异常,finally 代码块中的代码总会被执行。
在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。
finally 代码块出现在 catch 代码块最后:
注意下面事项:
catch 不能独立于 try 存在。
在 try/catch 后面添加 finally 块并非强制性要求的。
try 代码后不能既没 catch 块也没 finally 块。
try, catch, finally 块之间不能添加任何代码。

posted @ 2020-05-29 10:41  里克西西  阅读(223)  评论(0)    收藏  举报