80

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

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

PS:通过 Google 和 SO 进行搜索,但希望对此有明确的答案。

4

11 回答 11

62
  • 仅当您可以以有意义的方式处理异常时才捕获异常
  • 如果要由当前方法的使用者处理,则声明向上抛出异常
  • 如果它们是由输入参数引起的,则抛出异常(但这些通常是未经检查的)
于 2010-07-08T12:05:59.573 回答
15

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

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

  • 它是可以在本地处理的东西(例如尝试将输入字符串转换为数字,如果转换失败,则返回默认值是完全有效的),
  • 或者它不应该被抛出(例如,如果异常来自特定于实现的较低层,其实现细节不应该对调用者可见 - 例如,我不想显示我DAO用于Hibernate持久化我的实体,所以我在本地捕获所有HibernateExceptions并将它们转换为我自己的异常类型)。
于 2010-07-08T12:05:17.657 回答
12

这是我使用它的方式:

抛出:

  • 您只希望代码在发生错误时停止。
  • 如果不满足某些先决条件,则适用于容易出错的方法。

试着抓:

  • 当您希望程序因不同的错误而表现不同时。
  • 如果您想为最终用户提供 有意义的错误,那就太好了。

我认识很多人总是使用 Throws,因为它更干净,但几乎没有那么多控制。

于 2010-07-08T12:15:24.843 回答
9

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

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

注意:这个回复现在是一个社区维基,随时添加更多信息。

于 2010-07-08T12:06:08.247 回答
3

向您的方法添加 try-catch 或 throws 子句的决定取决于“您希望(或必须)如何处理您的异常”。

如何处理异常是一个广泛且远非微不足道的问题。它特别涉及决定在哪里处理异常以及在 catch 块中执行哪些操作。事实上,如何处理异常应该是一个全局的设计决策。

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

您必须决定要在哪里处理您的异常,并且该决定通常非常特定于您的域和应用程序要求。

于 2013-06-13T13:24:15.467 回答
2

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

于 2010-07-08T12:06:12.240 回答
1

如果一个方法可以对对象的状态、传递给该方法的任何参数以及该方法所作用的任何其他对象做出合理的保证,则该方法应仅throws作为例外。例如,一个方法应该从集合中检索调用者期望包含在其中throws的项目,如果期望存在于集合中的项目不存在,则该方法可能会检查异常。捕获该异常的调用者应该期望该集合不包含有问题的项目。

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

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

于 2013-06-13T19:16:38.510 回答
1

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

“但是作为开发人员,已检查的异常必须包含在方法的 throws 子句中。编译器有必要知道要检查哪些异常。按照惯例,未检查的异常不应包含在 throws 子句中。
考虑包含它们是糟糕的编程习惯。编译器将它们视为注释,并且不会检查它们。

资料来源:Kathy Sierra 的 SCJP 6 书

于 2018-12-23T11:17:31.213 回答
1

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

于 2021-01-19T09:00:19.040 回答
0

如果你使用 try catch,当异常发生时,剩余的代码仍然会被执行。

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

于 2017-03-13T07:26:52.353 回答
0

当您想提供自定义行为时使用 try-catch 对,以防万一发生异常......换句话说......您可以根据您的程序要求解决您的问题(异常发生)...... .

但是当您没有关于异常发生情况的任何特定解决方案时使用 throws...您只是不想让程序异常终止...。

希望它是正确的:-)

于 2018-06-21T17:38:32.797 回答