我什么时候应该宣布"投掷",什么时候不应该?



例如,我注意到这两个都在工作:

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,什么时候不宣布,然后扔掉它而不声明它?

选中的异常必须始终写入它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.");
}
Throws

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

从 JLS 第 11.2 节:

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

简而言之,如果检查异常,则需要 throws 语句。如果你有一个Exception,并且它不是RuntimeException的子类,那么它就会被检查。

IllegalArgumentExceptionRuntimeException 的一个子类,因此它是未选中的,你不需要在 throws 语句中声明它。大多数这样的例外情况(IllegalArgumentExceptionNullPtrException等)都是如此,因为不能合理地期望您轻松处理这些异常。

检查异常

时,编译器有义务捕获异常或宣布抛出声明。
查看这篇文章,了解已检查与未检查异常的比较。

这是因为IllegalArgumentException extends RuntimeException .你不能像这样把抛出子句留在下面。

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

有许多技术答案是JLS第1.2节,检查异常等,解释了它的用法。
但是你的问题

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

如果你的代码生成一些显式异常并抛出它,那么你应该总是添加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 天后如果您自己正在使用(我相信您将在不久的将来会重用它)这些函数,那么它将更有帮助,并且您将确切地知道我在该函数中做了什么。

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

最新更新