Jam*_*hon 14 java exception-handling exception
在查看Spring MVC框架时,我注意到,除非我误解,否则它的开发人员会抛出异常而不是抛出多个异常.
我意识到这个问题的核心是检查与未检查的异常辩论,避免宗教战争,使用抛出一般异常是一种好的做法吗?
Pau*_*lin 18
不,绝对不是.您应该指定要抛出的异常,以便调用者可以对每个异常执行正确的操作.如果不这样做,"throws Exception"会被链接传递,调用者可以做的最好的事情就是printStackTrace()并死掉.
更新:为了对抗某些"如果我覆盖方法"的反对意见,我会更进一步说,任何时候你有一个抛出异常的包(而不是从调用者传递异常),你应该在该包中声明一个异常类.因此,如果你覆盖我的"addToSchedule()抛出ScheduleConflictException",你就完全能够将ScheduleConflictException子类化为你需要的东西.
mat*_*t b 16
对于像Spring MVC这样需要开放以适应各种不同用例的库而言,有意义的是,在编写特定应用程序时,您不一定有意义.这是其中一个案例.
如果你指的是诸如Controller
接口等类作为方法签名之类的
handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception
Run Code Online (Sandbox Code Playgroud)
这可能是因为,从调用Controller的Spring类的角度来看DispatcherServlet
,它们并不关心你的代码调用什么类型的Exception - 库代码DispatcherServlet
只需要知道这个类可能会抛出异常因此能够在一般情况下处理异常.
换句话说,DispatcherServlet
不需要知道控制器可能抛出的异常的特定类型 - 它将把它们中的任何一个视为"错误".这就是方法签名的原因throws Exception
.
现在,API作者可以使签名使用自定义异常类型SpringMvcException
,但这只会强制您处理方法中的任何已检查异常类型handleRequest
并简单地包装它们,这是繁琐的make-work样板代码.因此,由于Spring的所有内容都旨在使您尽可能简单轻量地进行集成,因此它们更容易指定接口方法throws Exception
.
这是抛出特定异常的问题...假设某人扩展了您的类并希望覆盖您的方法.假设他们的新实现需要抛出不同类型的异常.(你怎么能够预测一个重写方法可能需要抛出的异常?)编写覆盖方法的人只有两个选择:1)自己处理异常(可能是一个糟糕的选择),或2)包装真实其中一个允许的异常类型中的异常并重新抛出.
但是选项2有两个问题.首先,当您将异常转储到日志文件时,您将获得长期丑陋的嵌套异常链.更重要的是,您将失去捕获特定异常的能力.例如,假设重写方法调用另一个与数据库对话的方法,并在结果SQL导致死锁时抛出DeadlockException.重写方法必须捕获此异常,将其包装在一个允许的类型中,然后重新抛出.这使得堆栈中的代码无法捕获并检测DeadlockException.
您的问题最终会进入关于已检查与未检查异常的争论的核心.你可以在Google上找到辩论双方的许多论据.我认为最终,如果您相信已检查的异常,您应该非常清楚方法抛出的异常.如果您不喜欢已检查的异常,则应声明每个方法都抛出异常.我落入后一阵营.
顺便说一句,对于那些不喜欢检查异常的人,我不喜欢在任何地方使用RuntimeException的想法.问题是您可能需要合并使用Exception而不是RuntimeException的第三方库.然后,您的代码将必须从库中捕获所有Exception并将它们包装在RuntimeException中.这造成了一团糟.
所以,如果我再次从头开始Java项目,我只是声明每个方法都抛出异常.
归档时间: |
|
查看次数: |
12761 次 |
最近记录: |