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. SqlHelper简单实现(通过Expression和反射)6.Providor模式(工厂+策略)可配置数据库选择

    基本思想,将MsSqlDbUtility和MySqlDbUtility设计成单例模式,通过App.config或Web.config进行默认的数据库设置,然后通过DbUtilityFactory获取D ...

  2. dubbo-admin 监控中心 部署

    dubbo-admin部署 下载: GitHub:https://github.com/search?q=dubbo-admin 百度网盘: 链接:https://pan.baidu.com/s/1v ...

  3. Centos编译安装 LAMP (apache-2.4.7 + mysql-5.5.35 + php 5.5.8)+ Redis

    转载地址:http://www.cnblogs.com/whoamme/p/3530056.html 软件源代码包存放位置:/usr/local/src 源码包编译安装位置:/usr/local/软件 ...

  4. [HNOI2019]校园旅行(构造+生成树+动规)

    题目 [HNOI2019]校园旅行 做法 最朴素的做法就是点对扩展\(O(m^2)\) 发现\(n\)比较小,我们是否能从\(n\)下手减少边数呢?是肯定的 单独看一个颜色的联通块,如果是二分图,我们 ...

  5. P(Y|X) 和 P(X,Y)

    P ( x | y ):在Y发生的条件下,X发生的概率.P ( x , y )P(x,y)说明该事件与两个因素有关,比如设是因素A,B.P(x,y)=P{因素A处于x状态,因素B处于y状态}确切地说P ...

  6. Mac系统安装MyEclipse

    参考链接 http://blog.csdn.net/jin_kwok/article/details/51925523

  7. MySQL表损坏修复【Incorrect key file for table】

    今天机房mysql服务器异常关机,重新启动后报错如下: -- :: [ERROR] /usr/local/mysql/bin/mysqld: Incorrect key file for table ...

  8. jsp中获取list长度

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ tag ...

  9. 转载 URL短地址压缩算法

    文章转载http://www.nowamagic.net/webdesign/webdesign_ShortUrlInTwitter.php /// <summary> /// 生成sal ...

  10. web服务器安全笔记

    一.设置项目目录权限(centos ,apache为例) 1.chown -R root /var/www/html/project   (设置项目所属的用户) 2.chgrp  -R root /v ...