疯狂Java程序员16堂课---第8课:异常捕捉的陷
2015-11-12 16:03
435 查看
第8课:异常捕捉的陷阱
这本书的每一章节的引言总能引人入胜,我喜欢这种情景引出问题来~
其实就是
问:当系统执行到catch 块代码中有return 时,系统是否还会执行对应的finally 块。
答:依然会执行finally 块里的代码。
再问:catch 里面有System.exit(0) ,Runtime.getRuntime().exit(0);时呢?………….
8.1正确关闭资源的方式:
实际开发中,数据库的连接,网络连接,磁盘文件等物理资源必须显示关闭,否则会引起资源泄漏。
(原以为 JVM提供的垃圾回收机制会回收,其实不会,因为它只负责回收堆内存中分配出来的内存,至于打开的物理资源无能为力。)
对于打开的物理资源:用finally 正确回收
注意3点:
1、 保证finall 会被执行
2、 关闭前保证资源引用的变量不为null
3、 多个资源的关闭单独用 try…catch 关闭,避免互相影响关闭
事例:
8.2 finally的陷阱(为了保证finally会被执行)
1、try中 有 System.exit(0);不会执行
2、try、catch中 有 return, finally 会执行。若finally中有return直接结束,否则返回try\catch中的return 结束.。
解释:执行到Try中的return时,并不会马上结束该方法,而是去寻找是否有finally 块。
3、 try、catch中抛出一个异常 , finally 会执行。
解释:类同2
8.3 catch的用法
8.3.1 catch 块的顺序。
多个catch ,排在前面的优先获得执行机会,那么多个catch 块的排列顺序的要求呢?
1、 捕捉父类异常的catch 应该在 子类异常之后,否则编译错误。
(先捕捉小的,再大的,犹如if…else,先处理小的再大的一样)
8.3.3 只能catch 可能抛出的异常
根据Java 语言规范,如果一个catch 子句试图捕获一个类型为XxxException 的Checked异常时,那么对应的try 块必须可能抛出XxxException 或及其子类的异常,否则编译错误。
首先贴上关于异常的种类的介绍:
通常,Java的异常(包括Exception和Error)分为可查的异常(checked
exceptions)和不可查的异常(unchecked exceptions)。
可查异常(编译器要求必须处置的异常):正确的程序在运行中,很容易出现的、情理可容的异常状况。可查异常虽然是异常状况,但在一定程度上它的发生是可以预计的,而且一旦发生这种异常状况,就必须采取某种方式进行处理。
除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
不可查异常(编译器不要求强制处置的异常):包括运行时异常(RuntimeException与其子类)和错误(Error)。
Exception 这种异常分两大类运行时异常和非运行时异常(编译异常)。程序中应当尽可能去处理这些异常。
运行时异常:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
非运行时异常 (编译异常):是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。(更多的/article/7644552.html)
代码解释:
IOException,ClassNotFoundException属于checked编译异常,代码中检测到
try中不可能抛出
而IndexOutOfBoundsException,NullPointerException属于RuntimeException的子类,属于运行时异常----只要愿意即可抛出
8.4继承得到的异常
Java 语言规定,子类重写父类方法时,子类方法只能声明抛出父类方法所声明抛出异常的子类。
代码解释:
子类实现了两个接口,两个接口的异常交集为空,所以子类不能声明抛出任意一种接口里面的异常。
这本书的每一章节的引言总能引人入胜,我喜欢这种情景引出问题来~
其实就是
问:当系统执行到catch 块代码中有return 时,系统是否还会执行对应的finally 块。
答:依然会执行finally 块里的代码。
再问:catch 里面有System.exit(0) ,Runtime.getRuntime().exit(0);时呢?………….
8.1正确关闭资源的方式:
实际开发中,数据库的连接,网络连接,磁盘文件等物理资源必须显示关闭,否则会引起资源泄漏。
(原以为 JVM提供的垃圾回收机制会回收,其实不会,因为它只负责回收堆内存中分配出来的内存,至于打开的物理资源无能为力。)
对于打开的物理资源:用finally 正确回收
注意3点:
1、 保证finall 会被执行
2、 关闭前保证资源引用的变量不为null
3、 多个资源的关闭单独用 try…catch 关闭,避免互相影响关闭
事例:
Finally{ If( oos != null){ Try{ oos.close(); }catch(Exception e){ e.printStackTrace(); } } If( ois != null){ Try{ ois.close(); }catch(Exception e){ e.printStackTrace(); } } }
8.2 finally的陷阱(为了保证finally会被执行)
1、try中 有 System.exit(0);不会执行
public class ExitFinally { public static void main(String[] args) throws IOException { FileOutputStream fos = null; try { fos = new FileOutputStream("a.bin"); System.out.println("程序打开物理资源!"); System.exit(0); } finally { //使用finally块关闭资源 if (fos != null) { try { fos.close(); } catch (Exception ex) { ex.printStackTrace(); } } System.out.println("程序关闭了物理资源!"); } } }
2、try、catch中 有 return, finally 会执行。若finally中有return直接结束,否则返回try\catch中的return 结束.。
解释:执行到Try中的return时,并不会马上结束该方法,而是去寻找是否有finally 块。
public class FinallyFlowTest { public static void main(String[] args) { int a = test(); System.out.println(a); } public static int test() { int count = 5; try { //因为finally块中包含了return语句, //则下面的return语句不会立即返回 return count++; } finally { System.out.println("finally块被执行"); return count++; } } }
3、 try、catch中抛出一个异常 , finally 会执行。
解释:类同2
public class FinallyFlowTest2 { public static void main(String[] args) { int a = test(); System.out.println(a); } public static int test() { int count = 5; try { //因为finally块中包含了return语句, //则下面的return语句不会立即返回 throw new RuntimeException("测试异常"); } finally { System.out.println("finally块被执行"); return count; } } }
8.3 catch的用法
8.3.1 catch 块的顺序。
多个catch ,排在前面的优先获得执行机会,那么多个catch 块的排列顺序的要求呢?
1、 捕捉父类异常的catch 应该在 子类异常之后,否则编译错误。
(先捕捉小的,再大的,犹如if…else,先处理小的再大的一样)
public class CatchSequenceTest { public static void main(String[] args) throws Exception { FileInputStream fis = null; try { fis = new FileInputStream("a.bin"); fis.read(); } //捕捉IOExcetion异常 catch (IOException ex) { ex.printStackTrace(); } //捕捉FileNotFoundException异常 catch(FileNotFoundException fex) { fex.printStackTrace(); } finally { //简单方式关闭资源 if (fis != null) { fis.close(); } } } }
8.3.3 只能catch 可能抛出的异常
根据Java 语言规范,如果一个catch 子句试图捕获一个类型为XxxException 的Checked异常时,那么对应的try 块必须可能抛出XxxException 或及其子类的异常,否则编译错误。
首先贴上关于异常的种类的介绍:
通常,Java的异常(包括Exception和Error)分为可查的异常(checked
exceptions)和不可查的异常(unchecked exceptions)。
可查异常(编译器要求必须处置的异常):正确的程序在运行中,很容易出现的、情理可容的异常状况。可查异常虽然是异常状况,但在一定程度上它的发生是可以预计的,而且一旦发生这种异常状况,就必须采取某种方式进行处理。
除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
不可查异常(编译器不要求强制处置的异常):包括运行时异常(RuntimeException与其子类)和错误(Error)。
Exception 这种异常分两大类运行时异常和非运行时异常(编译异常)。程序中应当尽可能去处理这些异常。
运行时异常:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
非运行时异常 (编译异常):是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。(更多的/article/7644552.html)
代码解释:
IOException,ClassNotFoundException属于checked编译异常,代码中检测到
try中不可能抛出
而IndexOutOfBoundsException,NullPointerException属于RuntimeException的子类,属于运行时异常----只要愿意即可抛出
8.4继承得到的异常
Java 语言规定,子类重写父类方法时,子类方法只能声明抛出父类方法所声明抛出异常的子类。
//定义第一个接口 interface Type1 { void test() throws ClassNotFoundException; } //定义第二个接口 interface Type2 { void test() throws NoSuchMethodException; } //该Test类实现Type1、Type2两个接口 public class Test implements Type1, Type2 { //实现Type1、Type2接口里声明的抽象方法 public void test() throws ClassNotFoundException { System.out.println("www.crazyit.org"); } public static void main(String[] args) { Test t = new Test(); t.test(); } }
代码解释:
子类实现了两个接口,两个接口的异常交集为空,所以子类不能声明抛出任意一种接口里面的异常。
相关文章推荐
- 黑马程序员——OC基础02—封装、继承、多态
- Java程序员到架构师的推荐阅读书籍
- 老程序员的10条告诫
- 15个IT程序员必须思考的问题
- ——黑马程序员——OC中集合对象的内存管理及copy的用法
- 高端ios面试总结
- 新浪也遇寒冬:全面停止社招—兄弟连IT教育
- 程序员的修炼
- 系统设计的高频面试题都有哪些?
- 编程面试过程中常见的10大算法概念汇总(Java版)
- 【转】老程序员的忠告:不要做浮躁的软件工程师
- 黑马程序员——OC基础01—类和对象
- JAVA面试题大全
- Android 面试精华题目总结
- 高效程序员的 7 个共同特征
- 百度面试题
- 面试题07-内存管理
- 面试题06-Foundation
- 程序员必备技能
- 面试题03-第三方框架