抛出或尝试+捕获
当决定是否将throws子句添加到方法或使用try-catch时,一般的经验法则是什么?
从我自己读过的内容来看,当调用者打破了合同结束时(被传递的对象),应该使用这个throws,并且当在一个正在进行的操作中发生exception时,应该使用try-catch方法。 它是否正确? 如果是这样,来电方应该做些什么?
PS:通过谷歌和SOsearch,但要在这一个明确的答案。
- 只有在能够以有意义的方式处理的情况下才能捕获exception
- 如果要由当前方法的消费者处理,则声明向上抛出exception
- 如果它们是由input参数引起的,则抛出exception(但是这些更常被取消选中)
一般来说,当一个方法无法在本地处理相关的问题时,它会向调用者抛出exception。 例如,如果该方法应该从具有给定path的文件中读取,IOExceptions不能在本地以合理的方式处理。 同样的情况也适用于无效input,我个人的select是在这种情况下抛出一个未经检查的exception,如IllegalArgumentException。
它应该从一个被调用的方法捕获exception,如果
- 这是可以在本地处理的东西(例如,尝试将inputstring转换为数字,如果转换失败,则返回默认值是完全有效的),
- 或者它不应该被抛出(例如,如果exception来自实现特定的低层,其实现细节不应该是可见的调用者 – 例如我不想显示我的DAO使用Hibernate持久我的实体,所以我在本地捕获所有HibernateExceptions,并将它们转换成我自己的exceptiontypes)。
我个人的经验法则很简单:
- 我能否以有意义的方式处理它(从评论中添加)? 所以把代码放在
try/catch
。 通过处理它,我的意思是能够通知用户/从错误中恢复,或者从广义上说,能够理解这个exception如何影响我的代码的执行。 - 在其他地方,把它扔掉
注意:这个回复现在是一个社区维基,随时添加更多的信息。
这是我使用它的方式:
抛出:
- 您只是希望代码在发生错误时停止。
- 如果不符合某些先决条件,那么很容易出错的方法。
试着抓:
- 当你想让程序的行为与不同的错误有所不同。
- 好极了,如果你想提供有意义的错误给最终用户。
我知道很多人总是使用Throw,因为它比较干净,但是只有很less的控制。
如果引发exception的方法有足够的信息来处理它,那么它应该捕获,生成关于发生了什么以及正在处理什么数据的有用信息。
添加try-catch或throws子句到你的方法的决定取决于“你想(或有)如何处理你的exception”。
如何处理一个exception是一个广泛而又非常微不足道的问题。 它特别涉及在哪里处理exception以及在catch块中执行什么操作的决定。 事实上,如何处理例外应该是一个全球性的devise决定。
所以回答你的问题,没有经验法则。
你必须决定你想处理你的exception,这个决定通常是非常特定于你的域和应用程序的要求。
如果一个方法能够合理地保证对象的状态,传递给方法的参数以及方法所作用的任何其他对象,则该方法只应throws
一个exception。 例如,假设从集合中检索调用者期望包含在其中的项目的方法可能会throws
一个检查的exception,如果预期存在于该集合中的项目没有。 捕获该exception的调用者应该期望该集合不包含有问题的项目。
请注意,虽然Java将允许检查的exception通过被声明为抛出适当types的exception的方法冒泡,但是这种使用通常应该被认为是反模式。 想象一下,例如,一些方法LookAtSky()
被声明为调用FullMoonException
,并且当月亮满时预计会抛出它; 进一步想象一下, LookAtSky()
调用ExamineJupiter()
,它也被声明为throws FullMoonException
。 如果ExamineJupiter()
引发了ExamineJupiter()
exception,并且LookAtSky()
没有捕获它并处理它或者以其他exceptiontypes封装它,那么调用LookAtSky
的代码会认为这个exception是地球满月的结果; 它不知道木星的卫星之一可能是罪魁祸首。
调用者可能期望处理的exception(包括基本上所有被检查的exception)应该只允许通过方法渗透,如果exception对方法的调用者来说意味着与被调用的方法相同。 如果代码调用一个被声明为抛出一些检查exception的方法,但调用者并不期望它在实践中抛出这个exception(例如,因为它认为它是预先validation的方法参数),那么检查的exception应该被捕获并包装在一些未经检查的exceptiontypes。 如果调用者不期望抛出exception,则调用者不能期望它具有任何特定的含义。
如果你使用try catch,当发生exception时,剩下的代码仍然会被执行。
如果您指出抛出exception的方法,那么当发生exception时,代码将会立即停止执行。