这就是受检异常和未受检异常的区别。
已检查异常是方法签名的一部分,需要在使用方法时被捕获或声明为抛出。它们是它们Exception
自己的子类。
一些示例包括 的特定构造函数Scanner
,或更正式地说,Scanner#<init>(File file)
。
已检查的异常通常被声明为抛出,因为它可以从异常中恢复。例如,如果您要创建一个Scanner
从文件中读取行的文件,并且该文件不存在,那么除了要求他们重新指定位置之外,您还能合理地做什么?
一个例子:
Scanner sc = new Scanner(System.in);
boolean found = false;
String path = sc.nextLine();
while(!found) {
try {
sc = new Scanner(new File(path));
found = true;
} catch (FileNotFoundException e) {
System.out.println(path + " was not valid. Please try again.");
path = sc.nextLine();
}
}
未经检查的异常不是方法签名的一部分,并且可能出于任何特定原因抛出。它们是 的子类RuntimeException
。
您会遇到的最常见的情况之一是NullPointerException
. 这种特殊的例外可能以最无害的方式发生,例如:
Integer i = null;
System.out.println(i + 2); // NPE on unboxing
通常不期望一个人能够从异常中恢复;用外行的话来说,关于代码流的假设出了问题。也就是说,写这个几乎可以肯定是代码异味:
Integer i = null;
try {
System.out.println(i + 2);
} catch(NullPointerException e) {
System.out.println("i was null!?");
}
大多数现代框架将允许您指定应用程序在发生此类错误时进入的特定状态 - 如果它是 Web 驱动的应用程序,您可以将这些类型的运行时异常处理为 500。
还有Error
, 这是未经检查的异常的一个特例——你绝对不应该从中恢复,因为它表明 JVM 出现了非常非常严重的错误。
例如,这是您不想看到的:
public void recurse() {
try {
recurse();
} catch (StackOverflowError e) {
System.out.println("We went in too deep.");
}
}