抛出或尝试+捕获

当决定是否将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时,代码将会立即停止执行。