锁定老帖子 主题:老掉牙的话题,java的异常处理。
精华帖 (1) :: 良好帖 (6) :: 新手帖 (12) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-03-20
Spring全都是runtime吗?
我觉得适合用runtime包的就是那些抛异常的api数目远远超过不抛异常的库,例如dao和远程调用,也就是说和checked刚好相反。 你不check是因为绝大多数甚至全部都有抛的可能性 没有checkedException我相信这些软件的平均健壮性不如java,就像c++的平均健壮性不如java一样 |
|
返回顶楼 | |
发表时间:2011-03-20
另外spring这些应用层面的大师考虑问题和语言层面的大师出发点不会完全一致,至于应该认同谁,每个人标准都会不同
|
|
返回顶楼 | |
发表时间:2011-03-20
引用 Rod Johnson的看法是除了用来进行流程控制的异常外,最好都转换成RuntimeException,除非你自己有能力去处理这个异常。
runtime不用检查,特性就是不强制捕捉,也不用强制声明,很容易一捅到底,所以都是null,wrong这些理应直接导致当机和code重写的异常来继承,这属于人祸,所以sql和rmi用runtime包也合理,因为这属于天灾,你自己、你的上层和上层的上层都恢复不了,可能一直要捅到界面或者程序中止,所以需要一捅到底的异常。重点就是:我弄出这种异常就是想一捅到底一了百了,别给那么多关卡
而checked则是本层要显式声明,上层要么继续转发,要么上层自己消化,所以这类异常显然不是天灾人祸,而是本层对可预见的自己无法处理的事件做转发,即在给调用前就明确要求调用者同意我能为你做某些事情,但有些情况如果出现我处理不了,我会把问题交给你,你可以给别人或者自己处理,这随你。重点就是:可预见,我处理不了,但上面某层有可能能处理,事情需要在某层被搞定,不能一溃千里。这就好比预料之中可能发生的小意外,但你自己处理不了,按照事先约定你需要明确推给你老板或者大老板接手,在哪层解决之后事情还得接着干。 引用 Rod Johnson 是 J2EE Design and Development (请参阅 参考资料) 的作者,这是我所读过的关于 Java 开发,J2EE 等方面的最好的书籍之一。他采取一个不太激进的方法。他列举了异常的多个类别,并且为每个类别确定一个策略。一些异常本质上是次要的返回代码(它通常指示违反业务规则),而一些异常则是“发生某种可怕错误”(例如数据库连接失败)的变种。Johnson 提倡对于第一种类别的异常(可选的返回代码)使用检查型异常,而对于后者使用运行时异常。在“发生某种可怕错误”的类别中,其动机是简单地认识到没有调用者能够有效地处理该异常,因此它也可能以各种方式沿着栈向上扩散而对于中间代码的影响保持最小(并且最小化异常淹没的可能性)。
引用 我已经发现非检查型异常的最大风险之一就是它并没有按照检查型异常采用的方式那样自我文档化。除非 API 的创建者明确地文档化将要抛出的异常,否则调用者没有办法知道在他们的代码中将要捕获的异常是什么。 有些问题其实已经在那个帖子很好的被讨论过 全盘将checked变成unchecked显然是走极端,java为runtime开的种种后门都是为了让这些异常一捅到底更容易,但显然不是所有的问题都是应该一捅到底。 如果一个在设计中应该中止于某层的异常是unchecked,那么实际开发中极有可能因为文档的问题而被忽略捕捉,结果一捅到底。事实上即使sql和rmi异常也常常中止于业务层,因为客户不关心也不理解这些异常信息或者因为有HA方案,所以这些异常在这种情况下应该杜绝一抛到底的特性。 同时sql,rmi这些也适合封成unchecked,因为: 1.异常类型单一,处理不需要多分枝 2.几乎所有api都抛,所以不需要考虑文档有没标注抛不抛,抛什么类型异常。调用者只用考虑自己是不是要拦截,不用一个个api都查文档确认。 3.可能确实有一抛到底的需求,就是每层都搞不定 |
|
返回顶楼 | |
发表时间:2011-03-20
checkedException导致乱吞最终的效果反而不如我刚说的倒追法,
好现在结论出来了: 对于严谨优秀的开发人员来说checkedException带来更多麻烦。 对于不严谨的状况,checkedException导致乱吞,问题严重,本根不如倒追法。 ———————————————————— 你没有回答这一部分。老是强调一抛到底本根就是奇怪的想法,你把调用方的思考至于何地? 他捕捉了他要捕捉的为什么会一抛到底,对于不严谨的场景来说经过多次迭代测试后很多该处理也被回补上去,这是倒追策略。 |
|
返回顶楼 | |
发表时间:2011-03-20
我已经发现非检查型异常的最大风险之一就是它并没有按照检查型异常采用的方式那样自我文档化。除非 API 的创建者明确地文档化将要抛出的异常,否则调用者没有办法知道在他们的代码中将要捕获的异常是什么。
———————————————————— 这段话看似有道理实则有误,对严谨的场景来说这个除非的论断成立,所以checkedException带来更多的是麻烦。 对于不严谨的场景来说checkedException驱动了更多乱吞异常的行为,反而带来更严重的后果。 而且从这段话的表述来看,似乎他承认我们真正需要的是一种便捷的说明方式。 |
|
返回顶楼 | |
发表时间:2011-03-20
ppgunjack 写道 另外spring这些应用层面的大师考虑问题和语言层面的大师出发点不会完全一致,至于应该认同谁,每个人标准都会不同
语言层面的设计者都支持checkedException?那这么多语言怎么没有checkedException,就连Java阵营自己都争议不断。而且趋势表明checkedException越来越少被使用。天平倒向何方已经很清楚了。 |
|
返回顶楼 | |
发表时间:2011-03-20
你一个模块,要么完成目标要么报告问题,你对上层除了他调用你要满足你的前置条件外,没有其他权利的要求。checkedException显然违反这一原则,明显发生混淆职责。
你到一个饭店吃饭,你点一到菜,服务员告诉你这道菜已经没有了(抛出了一个异常),你(调用方)会有很多可能,A顾客也许觉得无所谓没有就不吃这个了,B顾客觉得这事仍上去到老板那里才是合适的(可能是替老板订的),老板收到这个通知后说不行,我一定要搞定,于是自己拿了原材料要饭店加工。C顾客更牛,原材料随身带,立即恢复。 请问饭店会强迫你捕捉菜可能没有这个异常吗?站在饭店的角度(服务模块)要么搞定要么抛问题,哪有要用户强制捕捉问题的。菜没这个异常严重不严重,饭店(服务模块)其实是不确定的,关键在于A,B,C,。。。。的看法。 checkedException一直就是违反职责清晰原则的,他把本来调用方决定的事硬要揽在自己这边决定了。强暴调用者。 |
|
返回顶楼 | |
发表时间:2011-03-20
如果你把职责关系想清楚了就明白checkedException是在根本的理念上存在问题,它颠倒了权利关系。
|
|
返回顶楼 | |
发表时间:2011-03-20
所有陷入checkedException误区的人,都是只站在了方法实现方去想上面应该怎么怎么样,这就是在契约式设计之前,在前置条件,后置条件,不变式概念流行之前,很多实现API的人陷入的困境一样,如果调用方传入的参数不对怎么样?。。。。会陷入API设计上的泥潭,其实道理本来是很简单的你不符合我的前置条件我就抛出异常,就这么简单。当职责明确后模块的实现者就会轻松很多。不会陷入乱七八糟他本来不用管的各种复杂性泥潭。
|
|
返回顶楼 | |
发表时间:2011-03-20
我对checkedException 非常的反对,非常的不喜欢,不仅仅是什么过于学院化不实用之类的,而是从理念上认为它是错误的,因为它颠倒了权利关系。
处理什么错误的选择权是调用者的,而不是被调用方的,API方只有说明权不能侵犯调用者的选择权。因为你是服务的一方,你居然干涉用户的的选择,你强买强卖。这完全是对调用方的侵权行为。 |
|
返回顶楼 | |