Java中的受检异常

时间:2023-01-01 14:34:30

Java中的受检异常

Java提供了三种异常类型,受检异常(checked exception)、运行时异常(runtime exception)、错误(error)。那么这受检异常在实际开发中又有什么最佳实践呢?

受检异常

如果抛出的异常是可恢复的,同时我们也期望API的调用者捕获异常进行恢复处理,那么我们应该使用受检异常。受检异常会强迫API的使用者截获异常并恢复处理,或者进行声明继续抛出。

Java中的受检异常

图 1.IDE工具提示需要针对受检异常进行处理

Java中的受检异常

图 2.捕获受检异常并进行恢复处理

Java中的受检异常

图 3.重新声明受检异常

总而言之,对于可恢复的情况,使用受检异常;如果不清楚是否可能恢复,则最好使用未受检异常。

虽然受检异常是Java语言一项很好的特性,它强迫程序员处理异常,大大增强程序的可靠性。但是过分的使用受检异常会使API使用非常不方便,调用者必须在catch块中处理所有的受检异常,或者调用者必须声明抛出这些受检异常。

受检异常恢复的原子性

对于受检异常来说,我们期望在执行某个操作失败的时候,对象仍然保持在一种定义良好的可用状态之中,这样我们就可以从异常中进行恢复。一般而言,失败的方法调用应该使对象保持调用之前的状态,即受检异常的原子性。

我们有以下方式可以实现受检异常的原子性

1.使用不可变对象

如果对象不可变,那么在对象实例化的时候就确定了其状态,以后再也不能发生改变了,所以方法的执行就不能修改对象的状态,只能通过新建对象作为返回参数。

2.提前检查参数的有效性

在执行可变对象的方法之前检查参数的有效性,是的对象的状态被修改之前,先抛出适当的异常,这是可变对象获取受检异常原子性最常见的方法。

3.编写拦截操作失败并回滚对象状态的恢复代码。

4.现在临时拷贝的对象上执行操作,当操作成功后再用临时拷贝中的结果代替对象的内容。

虽然一般情况下大家都希望实现受检异常的原子性,但是并非总是可以做到的,例如缺少同步机制,并发修改同一个对象的状态。即使有时可以轻松实现受检异常的原子性,但是其可能会险种的增加开销和复杂性,并不一定是人们所期望的。