A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

这里写下我对 Java 中异常机制的理解,有些知识是来自书本和实践,有些则完全是我的个人观点,对不对的欢迎大家讨论指正


(博客原文链接: http://blog.csdn.net/raistlic/article/details/15807781

5 个回复

倒序浏览
0 - 异常的处理

=====

异常的处理应该尽量集中在某一层处理,处理异常的地方应该知道足够的上下文信息,知道应该如何处理异常。

对于异常的处理,用户代码(Client Code)掌握上面的简单原则就行了,这不是重点,——重点是异常的定义与抛出(使用)。
回复 使用道具 举报
1 - 异常前后,各相关部分的状态

某个异常何时发生?
因为什么发生?
一旦异常发生,各相关的对象(数据)都将处于何种状态?(所谓相关对象,就是说方法调用路径所经过的每一层的对象,从 new 异常的那一层一直到 catch 异常的那一层)
或者你无法预料这些对象、数据将会处于什么状态?
程序还能不能继续运行?
如果相关对象、数据在异常发生后都处于可以预料的稳定状态并且程序能继续运行,要不要提示信息给用户?
提示什么信息给用户?
异常有没有可能是用户操作错误导致的?
用户有没有办法通过更正操作等方式调用同一个功能,成功避免这个异常?
如果异常不是用户操作导致的,那么程序继续运行,用户做同样的操作,会不会总是发生这个异常?

=====

-> 如果异常发生后,你不能预料相关对象或数据的状态,或者你预料相关的对象或数据将会处于一种不稳定(或非法)的状态,比如对象内部的状态不再遵从其应有的约束(constraints),如果对对象进行进一步的操作,将会导致不可预料的行为………… 那么这种异常不可恢复,属于应该导致程序崩溃退出的异常。这时,显示友好的信息给用户,比如 “为了防止(对数据产生)更多的损害,程序将停止运行………………”,然后尽最大努力安全结束程序。

这样的异常,应该设计成非检查异常(unchecked exception),一般即 extends RuntimeException 或其子类型。

-> 如果异常是因为非法的用户输入导致的,那么应该在程序中避免,即非法的用户输入应该在其导致异常之前就检验出其不合法,然后不去调用功能,而是反馈合适的信息给用户。

如果检查输入的合法性代价非常昂贵,或者在调用功能之前无法检查其合法性:一种可能是这个功能的设计有问题;如果没有问题,就是无法在调用功能之前检查,或者检查太昂贵,那么就只能 try - catch,这时要明确一旦异常发生,整个调用路径的每一层都将出于什么状态,如果要确保异常发生之后程序能继续运行,那么每一层都应该处于原本调用之前的状态,就像调用没有发生一样。然后你就可以放心给用户提示信息,然后让用户重试了。

(在调用功能之前无法检查其合法性,这种情况大概多存在于多线程环境下,当某接口对外保证线程安全的时候)

这里的异常,可以设计成检查异常(checked exception),也可以设计成非检查异常。这是设计上的取舍问题,如果调用路径很长而你不愿意污染每一层方法的签名(throws),——那么设计成非检查异常。这里的核心问题是注明异常发生后的状态。

这里需要补充一句细节,多线程环境下,对于某后台线程发生的,而这个线程本身又不能处理的,应该导致程序崩溃退出的异常,使用 Thread.UncaughtExceptionHandler,具体用法可以查API文档。
回复 使用道具 举报
有没有简洁点的
回复 使用道具 举报
完全是背书呀
回复 使用道具 举报

完全是背书呀
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马