投掷或尝试捕获

时间:2010-07-08 12:01:33

标签: java exception exception-handling try-catch throws

在决定是否向方法添加throws子句或使用try-catch时,一般的经验法则是什么?

根据我自己读到的内容,当调用者违反合同结束(传递对象)时应使用throws,并且在发生异常时应使用try-catch正在该方法内执行的操作。它是否正确?如果是这样,应该在呼叫者方面做些什么?

P.S:通过Google和SO进行搜索,但希望能够对此进行明确的回答。

11 个答案:

答案 0 :(得分:50)

  • 只有在你能以有意义的方式处理它时才能捕获异常
  • 如果要由当前方法的使用者处理,则声明向上抛出异常
  • 抛出异常(如果它们是由输入参数引起的(但通常是未经检查的)

答案 1 :(得分:14)

通常,当一个方法无法在本地处理相关问题时,它应该向其调用者抛出异常。例如。如果该方法应该从具有给定路径的文件中读取,则IOExceptions无法以合理的方式在本地处理。同样适用于无效输入,并补充说我个人的选择是在这种情况下抛出未经检查的异常,例如IllegalArgumentException

如果出现以下情况,它应该从被调用的方法中捕获异常:

  • 它可以在本地处理(例如,尝试将输入字符串转换为数字,如果转换失败,则返回默认值完全有效),
  • 或者它不应该抛出(例如,如果异常来自特定于实现的下层,其实现细节不应该对调用者可见 - 例如我不想显示我的{{1}使用DAO来保存我的实体,所以我在本地捕获所有Hibernate并将它们转换为我自己的异常类型。)

答案 2 :(得分:9)

我个人的经验法则很简单:

  • 我能以有意义的方式处理 (从评论中添加)吗?所以把代码放在try/catch中。通过处理它,我的意思是能够通知用户/从错误中恢复,或者从更广泛的意义上说,能够理解这个异常如何影响我的代码的执行。
  • 在其他地方,扔掉它

注意:此回复现在是社区维基,随时可以添加更多信息。

答案 3 :(得分:7)

以下是我使用它的方式:

投掷:

  • 您只希望代码在何时停止 发生错误。
  • 很好的方法很容易 如果某些先决条件是错误 没见过。

Try-Catch:

  • 当你想要这个程序时 表现出不同的不同 错误。
  • 如果您想提供,那就太棒了 最终用户有意义的错误。

我知道很多人总是使用投掷,因为它更干净,但是控制力差不多。

答案 4 :(得分:3)

为您的方法添加try-catch或throws子句的决定取决于“您希望(或有)处理异常的方式”。

如何处理异常是一个广泛且极其微不足道的问题。它特别涉及决定处理异常的位置以及在catch块中实现的操作。事实上,如何处理异常应该是一个全局设计决策。

所以回答你的问题,没有经验法则。

您必须决定处理例外的位置,并且该决定通常非常适合您的域名和应用程序要求。

答案 5 :(得分:2)

如果引发异常的方法有足够的信息来处理它,那么它应该捕获,生成有关发生的事件和正在处理的数据的有用信息。

答案 6 :(得分:1)

如果方法可以围绕对象的状态,传递给方法的任何参数以及方法所依赖的任何其他对象做出合理的保证,那么该方法应该只有throws异常。例如,如果预期存在于集合中的项目不是,则假定从集合中检索调用者期望包含在其中的项目的方法可以throws检查异常。捕获该异常的调用者应该期望该集合不包含所讨论的项目。

请注意,虽然Java将允许已检查的异常通过声明为抛出相应类型的异常的方法冒泡,但这种用法通常应被视为反模式。例如,想象一下,某个方法LookAtSky()被声明为调用FullMoonException,并且当月亮满时,它会被抛出;进一步想象,LookAtSky()调用ExamineJupiter(),它也被声明为throws FullMoonException。如果FullMoonException抛出ExamineJupiter(),并且LookAtSky()没有捕获它并处理它或将其包装在其他异常类型中,则调用LookAtSky的代码会假设这个例外是地球月亮满了的结果;我们不知道木星的一颗卫星可能是罪魁祸首。

调用者可能期望处理的异常(包括基本上所有已检查的异常)只允许通过方法渗透,如果异常对方法的调用者意味着与调用方法的意义相同。如果代码调用一个被声明为抛出一些已检查异常的方法,但是调用者并不期望它在实践中抛出该异常(例如因为它认为它是预先验证的方法参数),那么应该捕获并包装已检查的异常在一些未经检查的异常类型中。如果调用者不期望抛出异常,则调用者不能指望它具有任何特定含义。

答案 7 :(得分:1)

何时使用什么。我对此进行了很多搜索。 没有硬性规定。

“但是作为开发人员,必须在方法的throws子句中包含Checked异常。这对于编译器知道要检查哪些异常是必需的。 按照约定,未经检查的异常不应包含在throws子句中。
包括它们被认为是不好的编程习惯。编译器将它们视为注释,并且不对其进行检查。“

来源:Kathy Sierra撰写的SCJP 6书

答案 8 :(得分:1)

我会让你变得简单。 当您认为被调用的方法不应对异常负责时使用 throws(例如,来自调用者方法的无效参数、要搜索的项目、在集合中无法获取或获取数据列表)。 当您认为被调用方法中的功能可能会导致某些异常时,请使用 try catch 块(处理被调用方法中的异常)

答案 9 :(得分:0)

如果使用try catch,则在发生异常时,其余代码仍将执行。

如果指出抛出异常的方法,那么当异常发生时,代码将立即停止执行。

答案 10 :(得分:0)

如果您希望提供自定义行为,则使用

try-catch对,以防万一发生异常.....换句话说,您可以根据程序要求解决问题(发生异常)。 ....

但是当您对异常发生情况没有任何特定的解决方案时,就会使用抛出方法……您只是不想使程序异常终止。...

希望它是正确的:-)