Java:声明未检查异常的最佳实践

Java:声明未检查异常的最佳实践,java,exception-handling,Java,Exception Handling,假设您有一些方法声明抛出未检查的异常 编辑:假设不是你设计了这个方法,而是一个非常受人尊敬的框架(Spring,aekhm!)的作者,你只是在说它 void someMethod() throws UncheckedException; 我的第一个问题是: 在throws子句中声明未经检查的异常是否有明确的原因 假设您有另一个方法调用someMethod void someOtherMethod() { someMethod() } 我的第二个问题是: 决定是否在someOtherM

假设您有一些方法声明抛出未检查的异常

编辑:假设不是你设计了这个方法,而是一个非常受人尊敬的框架(Spring,aekhm!)的作者,你只是在说它

void someMethod() throws UncheckedException;
我的第一个问题是:

  • 在throws子句中声明未经检查的异常是否有明确的原因
  • 假设您有另一个方法调用
    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
    子句中声明了throwing
    org.springframework.dao.DataAccessException
    。所以我想我的问题更多,如果我的代码调用这些方法,我是否应该声明抛出该异常,以及这样做(或不这样做)的原因是什么@artur我想如果Spring决定专门使用未检查的异常,也许他们觉得在
    抛出的
    中声明对手边没有javadoc的开发人员有一些小的好处。在这种情况下,我会将它们视为已检查的异常,并捕获任何您不希望冒泡到下一层的内容。如果您愿意(可以再次记住适当的抽象),可以考虑将它们封装在检查异常中。如果您还没有阅读第61项,请务必尝试获取副本。很明显,Spring违反了第62项,即在
    throws
    子句中没有声明未经检查的异常。我理解第61项。将未检查的异常视为已检查的异常会让我头晕目眩。我的意思是,一开始就不检查有什么意义。@artur如果你觉得你对这些异常无能为力,那就让它们冒出来吧。Spring的人可能选择了unchecked,因为他们认为你通常无法通过编程来解决这个问题。有关Hibernate的类似讨论,请参见。我理解(我认为)使用未经检查的例外的原因