6

例如,我注意到这两个都有效:

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,什么时候不宣布,直接扔而不声明?

4

7 回答 7

4

检查的异常必须始终写在它的方法签名中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.");
}
于 2013-10-22T11:45:54.083 回答
2

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

于 2013-10-22T11:48:25.437 回答
2

JLS 第 11.2 节

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

简而言之,如果检查throws了异常,则需要该语句。如果您有, 并且它不是 的子类,则检查它。 ExceptionRuntimeException

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

于 2013-10-22T11:45:48.933 回答
1

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

于 2013-10-22T11:46:28.240 回答
1

这是因为IllegalArgumentException extends RuntimeException. 您不能将 throws 子句留在下面的类似情况中。

public void func(int a) {
    if(a == 0) 
        throw new Exception("a should be greater than 0.");
}
于 2013-10-22T11:49:22.840 回答
1

有许多技术答案是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 天后正在使用(我相信您将在不久的将来重新使用它)这些功能,那么它将更有帮助,并且您将通过这些条款确切地知道我在该功能中做了什么.

于 2013-10-22T12:05:12.170 回答
0

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

于 2013-10-22T12:12:51.887 回答