例如,我注意到这两个都在工作:
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 的方法之前放置一个 try-catch 块。
从 JLS 第 11.2 节:
Java 编程语言要求程序包含 执行 方法或构造函数。对于每个检查的异常,这是一个可能的 结果,方法 (§8.4.6) 或构造函数的 throws 子句 (§8.8.5) 必须提及该例外的类别或 该异常类的超类 (§11.2.3)。
简而言之,如果检查异常,则需要 throws
语句。如果你有一个Exception
,并且它不是RuntimeException
的子类,那么它就会被检查。
IllegalArgumentException
是 RuntimeException
的一个子类,因此它是未选中的,你不需要在 throws 语句中声明它。大多数这样的例外情况(IllegalArgumentException
、NullPtrException
等)都是如此,因为不能合理地期望您轻松处理这些异常。
时,编译器有义务捕获异常或宣布抛出声明。
查看这篇文章,了解已检查与未检查异常的比较。
这是因为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