决定是在方法中添加throws
子句还是使用try-catch
?的一般经验法则是什么?
根据我自己的了解,throws
当调用方破坏了合同的末端(传递的对象)时,try-catch
应使用;当在方法内部执行的操作期间发生异常时,应使用。它是否正确?如果是这样,应该在呼叫方执行什么操作?
PS:通过Google和SO搜索,但希望对此有一个明确的答案。
决定是在方法中添加throws
子句还是使用try-catch
?的一般经验法则是什么?
根据我自己的了解,throws
当调用方破坏了合同的末端(传递的对象)时,try-catch
应使用;当在方法内部执行的操作期间发生异常时,应使用。它是否正确?如果是这样,应该在呼叫方执行什么操作?
PS:通过Google和SO搜索,但希望对此有一个明确的答案。
Answers:
通常,当方法无法在本地处理关联的问题时,该方法应向其调用方抛出异常。例如,如果该方法应该从具有给定路径的文件中读取,IOExceptions
则不能以明智的方式在本地进行处理。对于无效输入,同样适用,并补充说,我个人的选择是像IllegalArgumentException
在这种情况下一样抛出未经检查的异常。
并且它应该在以下情况下从调用的方法中捕获异常:
DAO
用途Hibernate
,因此我HibernateExceptions
在本地捕获所有内容并将它们转换为我自己的异常类型)。这是我的使用方式:
抛出:
试着抓:
我知道很多人经常使用Throws,因为它更干净,但控制权却不那么多。
我个人的经验法则很简单:
try/catch
。通过处理它,我的意思是能够通知用户/从错误中恢复,或者从更广泛的意义上讲,能够理解该异常如何影响我的代码的执行。注意:此回复现在是社区Wiki,请随时添加更多信息。
如果引发异常的方法有足够的信息要处理,那么它应该捕获并生成关于发生了什么以及正在处理哪些数据的有用信息。
如果方法throws
可以合理地保证对象的状态,传递给该方法的任何参数以及该方法所作用的任何其他对象,则该方法应该只有一个例外。例如,如果从集合中检索调用者希望包含在其中throws
的项目,则该方法可能会检查异常,如果预期存在于集合中的项目则不会。捕获到该异常的调用者应期望该集合不包含所讨论的项目。
请注意,尽管Java将允许经过检查的异常通过声明为适当类型的抛出异常的方法冒泡,但通常应将这种用法视为反模式。例如,想象一下,某个方法LookAtSky()
被声明为call FullMoonException
,并且有望在月球满时抛出该方法;进一步想象一下,该LookAtSky()
调用ExamineJupiter()
也称为throws FullMoonException
。如果aFullMoonException
被抛出ExamineJupiter()
,并且LookAtSky()
没有捕获并处理它或将其包装在其他异常类型中,则所调用的代码LookAtSky
将假定该异常是地球满月的结果。根本不知道木星的一颗卫星可能是罪魁祸首。
如果异常对方法的调用方意味着与被调用方法相同的含义,则仅应允许调用方期望处理的异常(包括基本上所有检查的异常)通过方法渗透。如果代码调用的方法声明为抛出某些已检查的异常,但是调用者不希望它在实践中抛出该异常(例如,因为认为它已预先验证了方法参数),则应捕获并包装已检查的异常在某些未经检查的异常类型中。如果调用者不希望引发异常,则调用者不能指望它具有任何特殊含义。