本节从优化程序的角度出发,介绍了正确运用异常处理机制的原则,遵守这些原则,可以提高程序的健壮性,并且有利于排除程序代码中的错误。
1.异常只能用于非正常情况
异常只能用于非正常情况,不能用异常来控制程序的正常流程。以下程序代码用抛出异常的手段来结束正常的循环流程。
这种处理方式有以下缺点:
➢ 滥用异常流程会降低程序的性能。
➢ 用异常类来表示正常情况,违背了异常处理机制的初衷。在遍历array 数组时,当访问到最后一个元素时,应该正常结束循环,而不是抛出异常。
➢ 模糊了程序代码的意图,影响可读性。如果把initArray()方法改为以下实现方式,就会使程序代码一目了然。
➢ 容易掩盖程序代码中的错误,增加调试的复杂性。例如以下程序的本意是找出数组中的最大值,把它赋给最后一个元素。由于编程人员误以为Java 数组的下标范围为1 到array.length,因此把数组最后一个元素表示为array[array.length]。当执行第一次循环时,就会抛出ArrayIndexOutOfBoundsExcetion 异常,从而结束循环。由于这个异常被捕获,程序在运行时不会异常终止,这使得编程人员难以发现程序代码中的错误。
2.尽可能地避免异常
应该尽可能地避免异常,尤其是运行时异常。避免异常通常有两种办法:
➢ 许多运行时异常是由于程序代码中的错误引起的,只要修改了程序代码的错误,或者改进了程序的实现方式,就能避免这种错误。
➢ 提供状态测试方法。有些异常是由于当对象处于某种状态时,不合适某种操作而造成的。
3.保持异常的原子性
应该尽力保持异常的原子性。异常的原子性是指当异常发生后,各个对象的状态能够恢复到异常发生前的初始状态,而不至于停留在某个不合理的中间状态。对象的状态是否合理,是由特定问题领域的业务逻辑决定的。
4.避免过于庞大的try 代码块
有些编程新手喜欢把大量代码放入单个try 代码块,这看起来省事,实际上却不是好的编程习惯。try 代码块越庞大,出现异常的地方就越多,要分析发生异常的原因就越困难。有效的做法是分割各个可能出现异常的程序段落,把它们分别放在单独的try代码块中,从而分别捕获异常。(www.daowen.com)
5.在catch 子句中指定具体的异常类
有些编程新手喜欢用catch(Exception ex)子句来捕获所有异常。例如,在以下打印机的print()方法中,用catch(Exception ex)子句来捕获所有异常,包括OutOfInk-Exception 和OutOfPaperException。
以上代码看起来省事,却不是好的编程习惯,理由如下:
➢ 对不同的异常通常有不同的处理方式。以上代码意味着对各种异常采用同样的处理方式,这往往是不现实的。
➢ 会捕获本应该抛出的运行时异常,掩盖程序中的错误。
正确的做法是在catch 子句中指定具体的异常类型。
6.不要在catch 代码块中忽略被捕获的异常
只要异常发生,就意味着某些地方出了问题,catch 代码块既然捕获了这种异常,就应该提供处理异常的措施。例如:
➢ 处理异常。针对该异常采取一些行动,比如弥补异常造成的损失或者给出警告信息等。
➢ 会重新抛出异常。catch 代码块在分析了异常后,认为自己不能处理它,重新抛出异常。
➢ 进行异常转译。把原始异常包装为适合于当前抽象层的另一种异常,将其抛出。
➢ 假如在catch 代码块中不能采取任何措施,那就不要捕获异常,而是用throws子句声明将异常抛出。
以下两种处理异常的方式是应该避免的。
或者:
在catch 代码块中调用异常类的printStackTrace()方法对调试程序有帮助,但程序调试阶段结束之后,printStackTrace()方法就不应再在异常处理代码块中担负主要责任,因为光靠打印异常信息并不能解决实际存在的问题。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。