一、关键技术点:
1、关键字finally用在try和catch语句之后,表示无论是否发生异常,都会执行finally块中的代码
2、一般情况下,先执行try块,如果有异常再执行catch块,最后才执行finally块,除非try块或者catch块中有跳转语句,如:return,那么在执行跳转语句之前,finally块中的代码被执行。因此,finally块中的代码一定会被执行。
3、由于finally块中的代码肯定会执行,所以常常将关闭资源(如关闭文件、数据库连接等)的语句放在fianlly中。
4、不要在finally块中用跳转语句,如return等,因为这会使得try和catch块中的跳转语句失效
二、演示实例
package book.exception;
/** *//**
* try catch finally的用法
* 无论是否发生异常,finally代码块始终都会执行
* @author joe
*
*/
public class Finally ...{
/** *//**
* 计算平方根
* @param nStr 数字的字符串
* @return 返回平方根
* @throws MyFirstException 当输入字符串为空,或字符串不能转化成数字时,抛出该异常
* @throws MySecondException 当输入字符串转化成的数字为负数时抛出该异常
*/
public static double getSqrt(String nStr) throws MyFirstException, MySecondException ...{
if (nStr == null) ...{
throw new MyFirstException("输入的字符串不能为空!");
}
double n = 0;
try ...{
n = Double.parseDouble(nStr);
} catch (NumberFormatException e) ...{
throw new MyFirstException("输入的字符串必须能够转化成数字!");
}
if (n < 0) ...{
throw new MySecondException("输入的字符串转化成的数字必须大于等于0!");
}
return Math.sqrt(n);
}
public static double testFinallyA(String nStr) ...{
try ...{
System.out.println("Try block! ");
return getSqrt(nStr);
} catch (MyFirstException e1) ...{
System.out.println("Catch MyFirstException block!");
System.out.println("Exception: " + e1.getMessage());
return -1;
} catch (MySecondException e2) ...{
System.out.println("Catch MySecondException block!");
System.out.println("Exception: " + e2.getMessage());
return -2;
} finally ...{
System.out.println("Finally block!");
}
}
public static double testFinallyB(String nStr) ...{
try ...{
System.out.println("Try block! ");
return getSqrt(nStr);
} catch (MyFirstException e1) ...{
System.out.println("Catch MyFirstException block!");
System.out.println("Exception: " + e1.getMessage());
return -1;
} catch (MySecondException e2) ...{
System.out.println("Catch MySecondException block!");
System.out.println("Exception: " + e2.getMessage());
return -2;
} finally ...{
System.out.println("Finally block!");
//增加一行,返回一个值
return 0;
}
}
public static void main(String[] args) ...{
System.out.println("使用testFinallyA方法:");
System.out.println("没有发生异常是输出:");
System.out.println("result: " + Finally.testFinallyA("123.4"));
System.out.println("发生异常时输出:");
System.out.println("result: " + Finally.testFinallyA("dfdg"));
System.out.println();
System.out.println("使用testFinallyB方法:");
System.out.println("没有发生异常是输出:");
System.out.println("result: " + Finally.testFinallyB("123.4"));
System.out.println("发生异常时输出:");
System.out.println("result: " + Finally.testFinallyB("dfdg"));
}
}
程序输出:
使用testFinallyA方法:
没有发生异常是输出:
Try block!
Finally block!
result: 11.108555261599053
发生异常时输出:
Try block!
Catch MyFirstException block!
Exception: 输入的字符串必须能够转化成数字!
Finally block!
result: -1.0
使用testFinallyB方法:
没有发生异常是输出:
Try block!
Finally block!
result: 0.0
发生异常时输出:
Try block!
Catch MyFirstException block!
Exception: 输入的字符串必须能够转化成数字!
Finally block!
result: 0.0
源码分析:
着重看testFinallyB方法的输出,在testFinallyB方法中的finally块总使用了跳转语句"return 0"。因为finally块的语句在try和catch中的跳转语句执行之前被执行,在执行finally语句中的跳转语句后,将无法执行try和catch中的跳转语句。所以该方法总是返回0.