捕获异常必须设置try/catch语句块,最简单的try语句:
try {
//code
//more code
} catch (ExceptionType e){
//handler for this type
}
1、如果在try语句中的任何代码抛出了catch子句中说明的异常类:
1)程序跳过try语句块的其余代码
2)程序执行catch字句中的处理器代码
2、如果try语句块中没有抛出任何异常类则跳过catch子句。
3、如果方法中任何代码抛出了在catch子句中没有声明的异常类型,该方法会立即退出。
public void read(String filename) {
try {
InputStream in = new FileInputStream(filename);
int b;
while ((b = in.read()) != -1) {
//process input
}
}
catch (IOException exception) {
exception.printStackTrace();
}
}
11.2.1捕获多个异常
try {
//code that might throw exceptions
}
catch (MalformedURLException e1) {
//emergency action for malformed URLs
}
catch (UnknownHostException e2) {
//emergency action for malformed hosts
}
catch (IOException e3) {
//emergency action for all other I/O problems
}
要想获得对象更多的信息,可以使用:e3.getMessage()
想得到详细的错误信息(如果有的话),使用:e3.getClass().getName()得到异常对象的实际类型
11.2.2再次抛出异常与异常链接
在catch子句中可以抛出一个异常,这样可以改变异常的类型。
下面是捕获异常并再次抛出的基本方法:
try {
//access the database
}
catch (SQLException e) {
Throwable se = new ServletException("database error");
se.initCause(e);
throw se;
}
捕获异常后可以用Throwable e = se.getCause();语句得到原始异常。
11.2.3Finally子句
不管是否有异常被捕获,都要执行finally子句中的代码。
下列例子程序将释放所以环境中的图形设备文本:
Graphics g = image.getGraphics();
try {
//1
code that might throw exceptions
//2
}
catch (IOException e){
//3
show error dialog
//4
}
finally {
//5
g.dispose();
}
//6
下列三种情况会执行finally子句:
1)代码没有抛出异常;程序执行1、2、5、6
2)抛出一个在catch处捕获的异常;执行1、3、4、5、6
3)抛出一个异常但不是由catch捕获的;执行1、5
try语句中可以只有finally子句没有catch子句,例如:
InputStream in = ...'
try {
code that might throw exceptions
}
finally {
in.close();
}
无论try中是否遇到异常,finally子句都被执行。
警告:当finally子句和try语句块中都有return语句时,finally的return值会覆盖掉try的return值。例如:
public static int f(int n) {
try {
int r = n * n;
return r;
}
finally {
if (n == 2)
return 0;
}
}
如果调用f(2),try的返回值是4,finally返回值是0,最后结果为0
11.2.4 分析堆栈跟踪元素
例11-1打印递归阶乘的堆栈情况:
package core.stacktracetest_11_1;
import java.util.Scanner;
/**
* @author vincent
*/
public class StackTraceTest {
public static int factorial(int n) {
System.out.println("factorial(" + n + "):");
Throwable t = new Throwable();
StackTraceElement[] frames = t.getStackTrace();
for (StackTraceElement f : frames)
System.out.println(f);
int r;
if (n <= 1) r = 1;
else r = n * factorial(n - 1);
System.out.println("return" + r);
return r;
}
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner in = new Scanner(System.in);
System.out.println("Enter n: ");
int n = in.nextInt();
factorial(n);
}
}