Java 进阶6 异常处理的陷阱 20131113
异常处理机制是 Java语言的特色之一,尤其是 Java的Checked 异常,更是体现了 Java语言的严谨性:没有完善的错误的代码根本就不会被执行。对于 Checked异常,Java 程序要么声明抛出,要不使用 try .. catch捕获程序运行过程中抛出的异常,进行处理。 Java开发程序员都是无法回避异常处理的情况, Java异常处理同样存在着一些迷惑的地方。例如在 finally代码块执行的规则是怎样的?程序中遇到 return语句之后还会执行finally代码块吗?程序遇到 System.exit()的时候还会执行finally代码块吗?
1. 正确关闭资源的方式
          实际的开发过程中经常需要打开一些物理资源,比如数据库连接、网络连接、磁盘文件等等,打开这些资源的之后必须要显式的关闭资源,否则会引起资源的泄漏。虽然 JVM有垃圾回收机制,但是对于这些资源, JVM是不会回收这些资源的, JVM只能够回收内存,而不能回收资源。
          传统的方式关闭资源,在 finally中
         finally{
         oos.close();ois.close(); 回收资源,但是这种方式不一定是安全的,因为在 oos ois未初始化的时候,程序运行就发生异常的话,那么 oos和ois 为完成初始化,这样的话, oos和ois 是没有必要关闭的。所以使用下面的方式关闭资源的话,是一种相对稳妥的方式。也就是在关闭之前,判断这些资源是否是有效的。
}
finally{if(oos != null) {oos.close();}  if(ois!= null ) { ois.close() ;}}
使用finally关闭资源的方式是比较安全的,保证关闭操作总是被执行;当关闭资源的时候,确保资源的引用变量是有效的资源而不是 null;为每个物理资源使用单独的 try…catch关闭资源,保证关闭资源的时候,引发的异常不会影响其他资源的关闭。
在Java7中引入的新的自动关闭资源的 try语言:它允许在try关键字之后紧跟一对圆括号,圆括号中可以声明,初始化一个或者多个资源,此处的资源是那些必须在程序结束的时候显式的关闭的资源。,比如数据库连接,网络服务等等。当 try语句结束的时候就会自动关闭这些资源。
需要注意的是为了保证 try语句正常关闭资源,这些资源类需要实现 AutoCloseable或者是Closeable 接口,实现这两个接口就需要实现 close方法。
 
try(
         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(“a.bin”));
         ObjectInputStream ois = new ObjectInputStream(new FileInputStream(“a.bin”));
){
oos.writeObject(obj);
oos.flush();
 
Object obj2 =(Object) ois.readObject();
}
这样的话,当超出 try代码块的时候,就会自动关闭打开的资源。需要注意的两点:
          被关闭的资源必须是实现 Closeable或者是AutoCloseable 接口;被关闭的资源必须是在 ()中声明、初始化的。
2.finally 代码块的陷阱
public static void main(String[] args)  {
         // TODO Auto-generated method stub
        FileOutputStream fos = null;
         try {
            fos = new FileOutputStream("Base.java" );
            System. out.println("successful open resource" );
            System. exit(0);
            
        } catch (FileNotFoundException e) {
             // TODO Auto-generated catch block
            e.printStackTrace();
        } finally{
             if(fos !=null ){
                 try {
                    fos.close();
                } catch (IOException e) {
                     // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            System. out.println("the program success close resource" );
        }
    }
这样的程序,不会输出 finally的内容。不论 try代码块是正常结束,还是中途非正常的推出, finally代码块都会执行,然而在这个程序中 try代码块根本就没有结束期执行过程,执行 exit的时候,将会停止当前线程还有所有其他当场死亡的线程, finally代码块不能够让停止的线程继续执行
     当System.exit(0) 的时候,JVM退出之前需要完成两项的清理工作:执行系统中注册的所有关闭钩子;如果程序中调用了 System.runFinalizerOnExit(true);那么JVM 就会对还没有结束的对象调用 finalizer;第二种方式是十分危险的,所以一般不会提倡;第一种方式是比较安全的操作。程序中将关闭的操作注册为关闭钩子,在 JVM退出之前,这些关闭钩子就会被调用,保证物理资源被正常关闭。
public static void main(String[] args) throws FileNotFoundException  {
         // TODO Auto-generated method stub
         final FileOutputStream fos;
        fos = new FileOutputStream("a.bin" );
        System. out.println(" 程序打开物理资源 ");
         Runtime.getRuntime().addShutdownHook(new Thread(){
             public void run(){
                 if(fos != null ){
                     try {
                        fos.close();
                    } catch (IOException e) {
                         // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System. out.println(" 程序正常关闭资源 ");
            }
        });
        System. exit(0);
    }
 
Finally 代码块
public static int test(){
         int count = 5;
         try{
             return ++count;
        } finally{
            System. out.println("finally code block");
             return count*2;
        }
        
    }
    public static void main(String[] args ) throws FileNotFoundException  {
         // TODO Auto-generated method stub
         int a = test();
        System. out.println(a);
    }
当 Java程序中执行 try代码块的时候遇到 return代码的时候, return语句会导致该方法立即结束,系统执行完 return语句的时候,并不会立即结束该方法,而是去寻找该异常处理流程中是否包含 finally代码块,如果有的话,则会执行 finally代码块,结束完成之后,在回到原来的 return语句中结束该方法;但是如果在 finally中如果有 return代码的话,就会直接在 finally中结束该方法。
 
Tengfei Yang
于广州中山大学 20131113

Java 进阶6 异常处理的陷阱的更多相关文章

  1. Java进阶5 面向对象的陷阱

    Java进阶5 面向对象的陷阱 20131103 Java是一门纯粹面向对象的编程语言,Java面向对象是基础,而且面向对象的基本语法非常多,非常的细,需要程序员经过长时间的学习才可以掌握.本章重点介 ...

  2. Java进阶02 异常处理

    链接地址:http://www.cnblogs.com/vamei/archive/2013/04/09/3000894.html 作者:Vamei 出处:http://www.cnblogs.com ...

  3. Java进阶02 异常处理(转载)

    异常处理 Java的异常处理机制很大一部分来自C++.它允许程序员跳过暂时无法处理的问题,以继续后续的开发,或者让程序根据异常做出更加聪明的处理. Java使用一些特殊的对象来代表异常状况,这样对象称 ...

  4. java进阶(19)--异常处理机制

    一.基本概念 1.异常的作用: java将异常信息打印至控制台,供程序修改,增加其健壮性. int c=1/0;    //将抛出 java.lang.ArithmeticException 2.异常 ...

  5. Java进阶03 IO基础

    链接地址:http://www.cnblogs.com/vamei/archive/2013/04/11/3000905.html 作者:Vamei 出处:http://www.cnblogs.com ...

  6. Java进阶4表达式中的陷阱

    Java进阶4表达式中的陷阱 20131103 表达式是Java中最基本的组成单元,各种表达式是Java程序员最司空见惯的内容,Java中的表达式并不是十分的复杂,但是也有一些陷阱.例如当程序中使用算 ...

  7. Java进阶篇(四)——Java异常处理

    程序中总是存在着各种问题,为了使在程序执行过程中能正常运行,使用Java提供的异常处理机制捕获可能发生的异常,对异常进行处理并使程序能正常运行.这就是Java的异常处理. 一.可捕获的异常 Java中 ...

  8. Java 进阶 hello world! - 中级程序员之路

    Java 进阶 hello world! - 中级程序员之路 Java是一种跨平台的语言,号称:"一次编写,到处运行",在世界编程语言排行榜中稳居第二名(TIOBE index). ...

  9. Java进阶(五)Java I/O模型从BIO到NIO和Reactor模式

    原创文章,同步发自作者个人博客,http://www.jasongj.com/java/nio_reactor/ Java I/O模型 同步 vs. 异步 同步I/O 每个请求必须逐个地被处理,一个请 ...

随机推荐

  1. spoj1812 LCS2 - Longest Common Substring II

    地址:http://www.spoj.com/problems/LCS2/ 题面: LCS2 - Longest Common Substring II no tags  A string is fi ...

  2. cocos2dx lua invalid 'cobj' in function 'lua_cocos2dx‘ 躺坑

    for 循环中保存了创建的 Node节点到 userdata 数据结构中 再次引用发现 一直报 LUA ERROR: [string ".\framework/cocos2dx/NodeEx ...

  3. 在Linux下不重启让配置文件修改后立即生效的办法

    在linux修改配置文件后可能没有生效,比如JDK文件配置,配置后可能没有生效,为了让文件生效,如下操作可以让配置文件生效. 例如,我刚修改了“/etc/profile”或“~/.bash_profi ...

  4. iOS开发之XMPPFramework环境搭建和配置

    1.mysql数据库安装和配置 官方下载地址:http://www.mysql.com/downloads/ 百度云盘地址: 安装软件参考:http://www.cnblogs.com/macro-c ...

  5. 微服务—分布式服务追踪sleuth和zipkin

    随着业务的发展,系统规模也会越来越大,各微服务间的调用关系也越来越错综复杂. 通常一个客户端发起的请求在后端系统中会经过多个不同的微服务调用来协同产生最后的请求结果, 在复杂的微服务架构系统中,几乎每 ...

  6. Python笔记 #03# Help!

    源:DataCamp datacamp 的 DAILY PRACTICE  + 日常收集. Functions Built-in functions Help! Multiple arguments ...

  7. 20145302张薇 《Java程序设计》第二周学习总结

    20145302张薇 <Java程序设计>第一周学习总结 教材学习内容总结 第三章 第三章讲的是基本类型,变量,运算符和基本条件语句. 基本类型分为: 整数:short(2 byte),i ...

  8. 20145314郑凯杰《信息安全系统设计基础》第6周学习总结 part A

    第4章 处理器体系结构 part 1 本部分对改章节的知识点进行总结: 一个处理器支持的指令和指令的字节级编码称为它的指令集体系结构(ISA). 不同的出路器有不同的ISA. ISA模型看上去应该是顺 ...

  9. Excel水平线画不直,图形对象对不齐,怎么办

    看够了千篇一律的数字报表,不妨添加些图形对象来调剂下,今天小编excel小课堂(ID:excel-xiaoketang 长按复制)给各位分享10个插入图形对象时简单实用的小技巧. 01课题 今天小编e ...

  10. HBase安装过程

    1).上传,解压,重命名,修改环境变量/etc/profile 2).修改 hbase-env.sh 文件 export JAVA_HOME=/usr/java/jdk1.7.0_27 //Java ...