【问题标题】:When should I announce "throws", and when not? [duplicate]我什么时候应该宣布“投掷”,什么时候不应该? [复制]
【发布时间】:2013-10-31 06:24:04
【问题描述】:

例如,我注意到这两种方法都有效:

public void func(int a) throws IllegalArgumentException {
    if(a < 0) 
        throw new IllegalArgumentException("a should be greater than 0.");
}

public void func(int a) {
    if(a < 0) 
        throw new IllegalArgumentException("a should be greater than 0.");
}

这让我问:

我应该什么时候宣布throws anException,什么时候不宣布,直接扔掉?

【问题讨论】:

    标签: java exception try-catch throw


    【解决方案1】:

    JLS Section 1.2, Checked exceptions 等有很多技术答案解释了它的使用。
    但是你的问题

    我应该什么时候宣布抛出异常,什么时候不应该,直接抛出而不声明它?

    如果您的代码正在生成一些显式异常并抛出它,那么您应该始终添加 throws 子句,并且应该通过在函数上方编写 /** 来生成文档这将为您生成文档标签。 这将帮助使用您的库或函数的所有其他用户,如果某些无效参数或某些值在调用此函数之前尚未初始化,则某些函数或构造函数必然会引发异常。

    示例

    /**
     * 
     * @param filePath File path for the file which is to be read   
     * @throws FileNotFoundException In case there exists no file at specified location
     * @throws IllegalArgumentException In case when supplied string is null or whitespace
     */
    public static void ReadFile(String filePath) throws FileNotFoundException, IllegalArgumentException 
    {
        if(filePath == null || filePath == "")
         throw new IllegalArgumentException(" Invalid arguments are supplied ");
        File fil = new File(filePath);
        if(!fil.exists()|| fil.isDirectory())
            throw new FileNotFoundException(" No file exist at specified location " + filePath);
        //..... Rest of code to read file and perform necessay operation
    }
    

    此外,这些文档标记和抛出使程序员的生活更轻松,他们将重用您的代码,并提前知道如果使用错误的参数调用函数或指定位置的文件不可用,将抛出 IllegalArgumentException、FileNotFoundException。

    因此,如果您希望您的代码和函数具有自我解释性,并提供所有必要的情况,则会引发哪些异常,请添加以下子句,否则您可以选择。
    请记住,如果您自己在 30 天后正在使用 (我相信您将在不久的将来重新使用它)这些功能,那么它会更有帮助,您将确切地知道这些功能子句我在那个函数中做了什么。

    【讨论】:

      【解决方案2】:

      虽然您需要声明已检查的异常, 未经检查的异常如果可以通过方法或构造函数的执行抛出,则不需要在方法或构造函数的 throws 子句中声明它们......来自 - http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html

      【讨论】:

        【解决方案3】:

        来自JLS section 11.2

        Java 编程语言要求程序包含 检查异常的处理程序,这些异常可能由执行 方法或构造函数。对于每个检查的异常,这是可能的 结果,方法(第 8.4.6 节)或构造函数的 throws 子句 (§8.8.5)必须提及该异常的类别或其中之一 该异常的类的超类(第 11.2.3 节)。

        简单地说,如果检查异常,您需要throws 语句。如果您有一个Exception,并且它不是RuntimeException 的子类,那么它会被选中。

        IllegalArgumentExceptionRuntimeException 的子类,因此它是未选中的,您不需要在 throws 语句中声明它。对于大多数此类异常(IllegalArgumentExceptionNullPtrException 等)来说都是如此,因为不能合理地期望您轻松处理这些异常。

        【讨论】:

          【解决方案4】:

          这是因为IllegalArgumentException extends RuntimeException。你不能把 throws 子句留在下面这样的情况下。

          public void func(int a) {
              if(a == 0) 
                  throw new Exception("a should be greater than 0.");
          }
          

          【讨论】:

            【解决方案5】:

            Throws 的美妙之处在于异常转换为检查异常,因此每次任何开发人员尝试使用第一种方法时,都会警告他在调用签名中包含 Throws 的方法之前放置一个 try-catch 块。

            【讨论】:

              【解决方案6】:

              当您的异常被检查时,编译器有义务捕获异常或宣布抛出声明。
              查看this 帖子以比较已检查和未检查的异常。

              【讨论】:

                【解决方案7】:

                检查的异常必须始终写在它throws的方法签名中。

                如果异常extend RuntimeException,则不必在方法名称中写throws,但强烈推荐,因为它更清晰,会在文档中提及方法。

                /**
                 * @throws This won't appear if you don't write `throws` and this might
                 * mislead the programmer.
                 */
                public void func(int a) throws IllegalArgumentException {
                    if(a < 0) 
                        throw new IllegalArgumentException("a should be greater than 0.");
                }
                

                【讨论】:

                • 不,建议 Effective Javathrows 中编写未经检查的异常。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2010-12-30
                • 2012-09-22
                • 2021-09-07
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多