java中的异常Exception和错误Error都派生自Throwable。在Exception下面,又区分了RuntimeException和其它异常。
Error类及其子类、RuntimeException类及其子类属于未检查(unchecked)异常。所有其它的异常属于已检查(checked)异常。
主要的区分原则是:对于可恢复的情况或者期望调用者适当地恢复的情况,使用已检查异常;对于往往不可恢复的情况,使用未检查异常。
对于已检查异常,如果函数(也包括构造函数)内部处理逻辑中使用throw语句抛出了,那么该函数的声明中必须明确使用throws子句来抛出,否则编译就会出错。对于未检查异常,在函数的声明中不需要使用throws子句来抛出。
如果方法抛出一个或者多个已检查异常,该方法的调用方要么用catch子句捕获这些异常(当然也可以捕获处理后再抛出);要么在函数声明使用throws子句继续抛出,让它们继续传播出去。对于方法内部处理逻辑抛出的未检查异常,该方法的调用方不要求进行捕获处理
示例代码:
在函数testException内部抛出了两个异常,一个是已检查异常IOException,另外一个是未检查异常SecurityException。在testException函数的声明中,必须明确使用throws IOException,否则就会编译出错。
调用方情况一:在main函数中调用了testException函数,没有用catch子句捕获,所以必须在main函数的声明中用throws IOException继续抛出:
import java.io.IOException;
public class Test2 {
public void testException() throws IOException {
int i = 11;
if ( i % 2 == 0) {
throw new IOException("found io exception");
} else {
throw new SecurityException("found security exception");
}
}
public static void main(String[] args) throws IOException {
Test2 test = new Test2();
test.testException();
}
}
调用方情况二:在main函数中调用了testException函数,用catch子句进行了捕获,没有继续抛出,此时main函数的声明中不用throws IOException:
import java.io.IOException;
public class Test2 {
public void testException() throws IOException {
int i = 11;
if ( i % 2 == 0) {
throw new IOException("found io exception");
} else {
throw new SecurityException("found security exception");
}
}
public static void main(String[] args) {
Test2 test = new Test2();
try {
test.testException();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
调用方情况三:在main函数中调用了testException函数,用catch子句进行了捕获,然后再抛出,此时必须在main函数的声明中用throws IOException继续抛出:
import java.io.IOException;
public class Test2 {
public void testException() throws IOException {
int i = 11;
if ( i % 2 == 0) {
throw new IOException("found io exception");
} else {
throw new SecurityException("found security exception");
}
}
public static void main(String[] args) throws IOException {
Test2 test = new Test2();
try {
test.testException();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new IOException("go on next processing", e);
}
}
}