Java:声明未检查异常的最佳实践
假设您有一些方法声明抛出未检查的异常 编辑:假设不是你设计了这个方法,而是一个非常受人尊敬的框架(Spring,aekhm!)的作者,你只是在说它Java:声明未检查异常的最佳实践,java,exception-handling,Java,Exception Handling,假设您有一些方法声明抛出未检查的异常 编辑:假设不是你设计了这个方法,而是一个非常受人尊敬的框架(Spring,aekhm!)的作者,你只是在说它 void someMethod() throws UncheckedException; 我的第一个问题是: 在throws子句中声明未经检查的异常是否有明确的原因 假设您有另一个方法调用someMethod void someOtherMethod() { someMethod() } 我的第二个问题是: 决定是否在someOtherM
void someMethod() throws UncheckedException;
我的第一个问题是:
someMethod
void someOtherMethod() {
someMethod()
}
我的第二个问题是:
someOtherMethod
中声明抛出UncheckedException
的最佳实践是什么Spring框架的异常基于未检查的异常。例如,一些方法抛出(并在
抛出中声明)DataAccessException。如果我的代码正在使用这些调用,它是否应该声明抛出这些异常?为什么呢?最佳实践是根本不声明未检查的异常。您不会看到这样的方法:
public void foo() throws NullPointerException {...}
您应该只对选中的异常使用抛出。通过说throws
你期望clinet以任何方式处理他的异常,而这对于未检查的异常是不正确的
编辑:
评论中进行了一些热烈的讨论,所以我想澄清一下:您不必声明未检查的异常
,这并不意味着您不能,尽管在大多数情况下您不应该这样做。我更喜欢在javadoc风格的注释中提到它们,而不是在throws
子句中。还有很多其他的例子,你通常不应该做某事,但在某些情况下你可能需要做。在我看来,底线是:不,您不应该在throws子句中列出未检查的异常
,我建议您阅读好书《有效Java》中的第9章。你将得到所有问题的答案,你将享受一个伟大的阅读
特别针对您的问题:
使用Javadoc@throws标记记录每个未检查的异常
方法可以抛出,但不要使用throws关键字来包含
方法声明中未检查的异常
不需要在方法的throws…
子句中声明未检查的异常。如中所述,“允许但不要求在throws子句中提及未经检查的异常类”
如果您预计API的用户可能会遇到未经检查的异常,通常会在Javadoc中列出这些异常。一个常见的例子是列出可能引发IllegalArgumentException
的原因
如果您将一个方法与另一个方法包装在一起,请应用有效的Java原则,即抛出适合抽象级别的异常(第61项)。这应该适用于已检查的异常和预期的未检查异常。在我看来,最佳做法是在未检查异常的方法头部不使用抛出,但不要忘记记录方法抛出的每个异常(已检查或未检查):
/**
* Some doc
* @throws IllegalArgumentException if ...
*/
public void m() {
//...
throw new IllegalArgumentException();
}
记录您的API是一件好事,声明一个throws或将@throws添加到javadoc中都是很好的实践。它只是让读者更加明白,这从来都不是一件坏事。我并不总是这么做,但一般来说,你希望人们意识到有些事情可能会失败。我不会为NPE这样做,但输入验证错误或授权错误是您可能需要记录的内容。看看Java标准库。到处都有未检查异常的声明!是的,到处都没有有意义的变量名,这也不是一个好的做法……在javadoc文档(例如官方Java API中的NullPointer
)中还提到许多未检查的异常是一个常见的做法,这是一个文档,而不是实际的代码。而且它仍然不能表明这是一个好的选择practice@Thirler:docstring的@throws
中提到了未经检查的异常,但它们是否真的是在方法的性质中声明的?@Raedwald Partial duplicate的可能重复。我知道没有必要声明未经检查的异常,但是Spring的人出于某种原因决定了他们会这样做(所以我猜他们这样做是有原因的)。此类的许多方法org.springframework.orm.ibatis.SqlMapClientTemplate
在其throws
子句中声明了throwingorg.springframework.dao.DataAccessException
。所以我想我的问题更多,如果我的代码调用这些方法,我是否应该声明抛出该异常,以及这样做(或不这样做)的原因是什么@artur我想如果Spring决定专门使用未检查的异常,也许他们觉得在抛出的中声明对手边没有javadoc的开发人员有一些小的好处。在这种情况下,我会将它们视为已检查的异常,并捕获任何您不希望冒泡到下一层的内容。如果您愿意(可以再次记住适当的抽象),可以考虑将它们封装在检查异常中。如果您还没有阅读第61项,请务必尝试获取副本。很明显,Spring违反了第62项,即在throws
子句中没有声明未经检查的异常。我理解第61项。将未检查的异常视为已检查的异常会让我头晕目眩。我的意思是,一开始就不检查有什么意义。@artur如果你觉得你对这些异常无能为力,那就让它们冒出来吧。Spring的人可能选择了unchecked,因为他们认为你通常无法通过编程来解决这个问题。有关Hibernate的类似讨论,请参见。我理解(我认为)使用未经检查的例外的原因