11.2 捕获错误
11.2 捕获异常
捕获异常必须设置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); } }