老掉牙的话题,java的异常处理。关于系统中的异常怎么处理,之前也看过很多的文章。只是觉得越看越糊涂,大家持
老掉牙的话题,java的异常处理。
关于系统中的异常怎么处理,之前也看过很多的文章。只是觉得越看越糊涂,大家持很多不同的意见。
现在想形成一套自己的观点,合自己口味的解决方案。没有对与不对,因人而宜。
?
DataAccessException extends RuntimeException? Dao层异常
ServiceException extends RuntimeException?? Service层异常
我被java的RuntimeException和Exception的使用一直弄得头晕。
现在的观点是,把Exception转化成RuntimeException,省的方法还throws,个人觉得的throws看起来不爽,呵呵。
这就相当于在自己写代码过程中放弃了使用Exception。减少烦恼
但是有些自己写的工具类当中又是怎么处理呢。抛还是不抛(通过返回值),抛什么?
?
欢迎大家发表下意见,批评改正。
?
170 楼 ppgunjack 2011-03-21 没收获太多,bruce自己写java代码我觉得也不算风格多好,import *在demo中比比皆是,无模板类型声明的调用也比比皆是,他对语言特性有敏锐的感觉,但未见得所有观点都能从应用开发和软件管理出发
这篇文章也是反复说两点吞异常和接口污染
分开说
1.吞异常是态度问题。
下级来异常,要么扩展接口向上抛,要么代码吞,如果吞了,至少说明他认为问题应中止于此,也不需要做什么,如果不应该他消化的他也照吞只为了图简便,那还是开了他吧。
这样的人更不会好好对待下层上来的和自身的unchecked exception,也不用指望他能好好注明文档。应该止于此处的excpetion很可能就被轻而易举抛到上层,而上层对这种可能性一无所知,毫无保护,因为这样的人懒得要吞checked异常就更不会为下面那些很难估计的unchecked去考虑完善文档,指望测试搞定这些不可预计的异常?拉到吧,国内绝大部分公司连ifelse支路测试覆盖都过不了80%,就别谈哪些unchecked异常了
2.接口污染
确实有这个问题,异常成为了接口一部分会影响上层
但是你要明白,checked 异常和返回类型、函数签名一样,你用了,就已经被侵入了,你怎么不质疑为什么函数调用返回不能是obj或者void*,我自己决定转不转型,你返回你的类型不是强迫我import或者include返回值类型定义吗?这不是服务端强暴调用端吗?为什么你要有时返回空指针,不能返回空对象,害得调用端还要判断,这不又是强暴吗?
一个接口7,8个异常,这是设计层面的问题
每个层应该有自己的异常,层内部本身应该转义,你给客户看个spring初始化文件读取错误的异常有意义吗?这样即使深层次的嵌套异常也不会爆炸。
因为checked实际已经把异常上升到签名级别就导致侵入是一定的,所以设计必须谨慎,要确认应该由调用这处理异常或者恢复的情况才使用
既然你那么认同公仆论,那干脆也不发你工资了,这个异常你作为runtime向上抛好了,别强求别人catch了,有些人喜欢checkedException,因为这会有当领导的感觉,有哥说了算的感觉。结果苦了调用方。 171 楼 carlkkx 2011-03-21 ppgunjack 写道没收获太多,bruce自己写java代码我觉得也不算风格多好,import *在demo中比比皆是,无模板类型声明的调用也比比皆是,他对语言特性有敏锐的感觉,但未见得所有观点都能从应用开发和软件管理出发
这篇文章也是反复说两点吞异常和接口污染
分开说
1.吞异常是态度问题。
下级来异常,要么扩展接口向上抛,要么代码吞,如果吞了,至少说明他认为问题应中止于此,也不需要做什么,如果不应该他消化的他也照吞只为了图简便,那还是开了他吧。
这样的人更不会好好对待下层上来的和自身的unchecked exception,也不用指望他能好好注明文档。应该止于此处的excpetion很可能就被轻而易举抛到上层,而上层对这种可能性一无所知,毫无保护,因为这样的人懒得要吞checked异常就更不会为下面那些很难估计的unchecked去考虑完善文档,指望测试搞定这些不可预计的异常?拉到吧,国内绝大部分公司连ifelse支路测试覆盖都过不了80%,就别谈哪些unchecked异常了
2.接口污染
确实有这个问题,异常成为了接口一部分会影响上层
但是你要明白,checked 异常和返回类型、函数签名一样,你用了,就已经被侵入了,你怎么不质疑为什么函数调用返回不能是obj或者void*,我自己决定转不转型,你返回你的类型不是强迫我import或者include返回值类型定义吗?这不是服务端强暴调用端吗?为什么你要有时返回空指针,不能返回空对象,害得调用端还要判断,这不又是强暴吗?
一个接口7,8个异常,这是设计层面的问题
每个层应该有自己的异常,层内部本身应该转义,你给客户看个spring初始化文件读取错误的异常有意义吗?这样即使深层次的嵌套异常也不会爆炸。
因为checked实际已经把异常上升到签名级别就导致侵入是一定的,所以设计必须谨慎,要确认应该由调用这处理异常或者恢复的情况才使用
既然你那么认同公仆论,那干脆也不发你工资了,这个异常你作为runtime向上抛好了,别强求别人catch了,有些人喜欢checkedException,因为这会有当领导的感觉,有哥说了算的感觉。结果苦了调用方。
关于第一点,你只要观察一下现实就知道了。你个人之力能抵得上洪水?一种语言特性加速了这种现象发生岂能只怪人。
这里我已经反复强调了:
对于菜鸟,倒追法好于乱吞,而且一个人反复被追到会使得他建立起对于异常的正确认识。你有何话说?
对于严谨的人来说,checkedException带来麻烦,他被迫需要应对很多他本不能处理的东西。扰乱视听。你有何话说?
最后您能直接回答对这个理念的看法吗?
选择处理什么样的错误是不是调用者的选择权?你出于什么样的理论或理念能支撑你侵犯这个选择权?
172 楼 carlkkx 2011-03-21 除了自大,或者类似于本朝公仆,事实没有什么理念能支撑你这么做,因为你已经考虑你模块以外的事情,当你在想这个他必须要处理那个他必须怎样时,你已经越过界线,已经把自己扮演上帝角色来指点江山了,而不是做好自己本模块的工作。乍一看你可能还委屈,因为你为劳苦大众好,但是实际上这种趋势反而导致复杂性增加。
173 楼 carlkkx 2011-03-21 要确认应该由调用这处理异常或者恢复的情况才使用
————————————————————
请问你怎么确认的了,如果服务方也是你,调用方也是你,你爱咋折腾就怎么折腾,但如果你是发布给别人的API,而且如果公共性很强的话,你就越确认不了了,就像Java标准库里面的情况,也许当初他们也是信誓坦坦的,但最终民意表明不过是他们一厢情愿,自以为是而已。 174 楼 carlkkx 2011-03-21 既然你那么认同公仆论,那干脆也不发你工资了,
——————————————
晕,服务方不代表无条件服务的,你让他服务要满足它的前置条件,我们再拿饭店举例子。
你到饭店吃饭至少要满足一个很重要的前置条件,那就是付钱。但是尽管如此,饭店也不会在你进去吃饭前强制你先catch万一没钱做好异常的防御,比如带上头盔以保护万一被揍。
服务当然可以抛出异常,这个异常有些可能是不满足前置条件,有些可能因为其他原因无法完成目标,但是断无强制让调用者必须catch什么,因为这是调用者的事,如果这个异常确实应该要这个调用者处理但是调用者没处理,那也是调用者的责任,与你的模块无关。这才叫清晰职责,这才能降低复杂性,
其实整个社会也是因为契约理念的使用,才使得如此复杂庞大的商业化活动成为可能。如果手互相乱伸的话,势必加大模块之间的依赖关系,最终反而使得复杂性加大,系统难以为继。 175 楼 carlkkx 2011-03-21 人类历史在进入长期严格等级制度后,终于有些明白无为而无不为的道理,面对复杂系统,自顶向下,中央严格控制模式(比如计划经济)必败无疑。市场经济对等级制度瓦解是历史上从来没有过的。但是其核心理念是非常微小的。这可能是少即是多的最佳实例。 176 楼 ppgunjack 2011-03-21 你觉得你吃饭,饭店会没准备catch你吃霸王餐的异常吗
你到赌场也这么想吗
你和老板在到高危地方干活,老板交代你干事会不事先准备应急预案吗?
遇到小异常你可以邮件,可以留纸条,这是老板可忽略事件,结果你在的酒店被炸了,这个异常你还会发邮件或者让别人留个纸条在老板桌上让老板可忽略吗?你如果还是不选择类似电话这种强制应答我就真有点佩服你了。
你让这个问题runtime,ok,结果老板很快也被炸,老板的老板也可能被你老板的忽略弄完蛋
老拿图异常和倒追测试说事,你测试真那么靠谱,吞异常都查不出来吗,明显异常支路没有正确输出,还要等到异常炸到根才能捕捉到?
别动不动谈政经,不懂平衡妥协和多面性根本理解不了这些领域的东西,没有绝对的好和坏,只有适用不适用,什么环境适用不适用
177 楼 carlkkx 2011-03-21 ppgunjack 写道你觉得你吃饭,饭店会没准备catch你吃霸王餐的异常吗
你到赌场也这么想吗
你和老板在到高危地方干活,老板交代你干事会不事先准备应急预案吗?
遇到小异常你可以邮件,可以留纸条,这是老板可忽略事件,结果你在的酒店被炸了,这个异常你还会发邮件或者让别人留个纸条在老板桌上让老板可忽略吗?你如果还是不选择类似电话这种强制应答我就真有点佩服你了。
你让这个问题runtime,ok,结果老板很快也被炸,老板的老板也可能被你老板的忽略弄完蛋
老拿图异常和倒追测试说事,你测试真那么靠谱,吞异常都查不出来吗,明显异常支路没有正确输出,还要等到异常炸到根才能捕捉到?
别动不动谈政经,不懂平衡妥协和多面性根本理解不了这些领域的东西,没有绝对的好和坏,只有适用不适用,什么环境适用不适用
你有没有发现你举得例子,都是你到什么什么地方如何如何,你注意是你到。。。。。,即你在扮演调用者而不是服务者,你调用者认为这里有不安全你预先catch,这有什么问题,这本来就是调用者的选择权,关键是那些服务的地方有没有强迫你catch什么。 178 楼 carlkkx 2011-03-21 老拿图异常和倒追测试说事,你测试真那么靠谱,吞异常都查不出来吗,明显异常支路没有正确输出,还要等到异常炸到根才能捕捉到?
————————————————————
当然是异常报告出来才容易发现问题,吞了异常,只是程序发生没按预期的行为走,如果情况复杂的话,查起来当然麻烦。 179 楼 carlkkx 2011-03-21 别动不动谈政经,不懂平衡妥协和多面性根本理解不了这些领域的东西,没有绝对的好和坏,只有适用不适用,什么环境适用不适用
————————————————————
你是老马fans,我可不是,我反老马比反CheckedException还坚决。中国人是很会玩弄政治,就是你所谓艺术性确实很高,但是这只是让社会增加内耗,商业社会越发达的地方信用越高。 180 楼 ppgunjack 2011-03-21 算了,你既然runtime先天就是有可忽略特性,你的调用者忽略你的可能性远大于checked
显然你认为911和110不是被用来强制接受异常,你以后就打10086吧,回追也能帮到你的 181 楼 ppgunjack 2011-03-21 认识差距太大,你说的我没啥不懂,我说的你一概不听,这个问题没多少我还需要思考和澄清的,到此为止 182 楼 ppgunjack 2011-03-21 补充一点,
checked异常应该在确认调用者应该予以解决的地方抛出,也就是说checked应该代表着要求在最近的某个层可恢复,这个异常应该尽量在靠近抛出点被解决和消化,因为只有最近的几层才最有恢复的可能,抛到最上层很多现场和引用已经失效,除了log对于恢复已经毫无能力,那此时checked不如转义为unchecked更为方便 183 楼 carlkkx 2011-03-21 ppgunjack 写道认识差距太大,你说的我没啥不懂,我说的你一概不听,这个问题没多少我还需要思考和澄清的,到此为止
不是不听,听了,只是我不认同。因为我始终坚持考虑有什么危险的问题是调用者的责任,服务方做到各种告知责任已到。
而你做了一个假设,如果不强制的话,一定会一桶到顶,即调用者是不思考的,调用者一定会犯错,我一定要保护他们。而这种强制可能恰恰产生问题,因为你忘了你也会犯错,你很可能做了你认为确定但是是错误的强制。
其实你的这种理念和本朝的口吻有相似之处,比如很多领域不开放市场由央企独家垄断,本朝是怎么解释的呢?大致是这样的:这些行业关乎国计民生,所以不能开放,只有在D和ZF的领导下才能有序的运行,否则一定会造成。。。。。。此处省略很多字。
184 楼 carlkkx 2011-03-22 我又想了一下,发现你的理念来源于长期处于checkedException之后造成,checkedException造成的职权关系错论导致长期处于这种理念下的人存在错误的依赖症,即明明应该是调用者要做的决定,明明应该是调用者的责任,明明应该是要调用者有的主见,统统没了,统统变成服务方应该要预先想好,使得调用者完全变成依赖者,连你应该要捕捉哪些异常服务方都替你决定了。当我们批评checkedException时,持有错误依赖症的人会突然觉得不可思议,但是实际上这本根就是用错误世界里面的错误依赖症去看待一个正常权利关系的世界。
好比在市场经济之前,很多人担心市场经济导致混乱一样,这本根就是用一个之前世界里面的错误观点去硬套另一个世界。 185 楼 ppgunjack 2011-03-22 人服务于社会,一个作为社会一员的服务方的小角色正企图以服务方不应该干涉调用方的理论来干涉社会这个调用方的工作逻辑,真是个悖论 186 楼 carlkkx 2011-03-22 ppgunjack 写道人服务于社会,一个作为社会一员的服务方的小角色正企图以服务方不应该干涉调用方的理论来干涉社会这个调用方的工作逻辑,真是个悖论
我不认为有什么悖论,而是一个平等权利关系的划分问题,你把所有的责任都推给服务方,连调用方要捕捉哪些异常都给决定了,这也类似父母溺爱孩子,造成本该孩子的责任都不存在了,权力关系发生错乱后,必然形成一个一边倒的依赖症。而不是权力责任自洽的完整体。 187 楼 allenofchina 2011-04-17 标准答案是
用CheckedException
业务层抛出一个通用的基类Exception
这个exception只在程序出现无法恢复的异常采用,数据之类可恢复的异常一概不用exception
业务层无论产生或不产生exception都需要声明throws exception
理由如下
1.业务经常变化,exeption太多将来改不起
2.这类异常都交由特定类处理,业务层不处理,直接throw就好
3.uncheckedexeption需要开发人员有比较高的技巧,而且不易于维护。可能是个很优雅或者很方便,但是现今中国不实用
4.这个属于design by contract的一部分,以后自己去翻相关文档即可 188 楼 lan861698789 2011-04-17 来看看学习下