jdk1.7中try-with-resources语法糖详解

首先回忆一下jdk1.7以前,咱们要经过流读取文件时,代码要怎样写?java

假设本地文件系统d盘下有一个in.txt文件,代码以下:编码

FileInputStream in = null;
		try {
			in = new FileInputStream("d:/in.txt");
		} catch(Exception e) {
			System.out.println(e.getMessage());
			throw new RuntimeException("try块中产生了异常",e);
		} finally {
			if (in != null)
				in.close();
		}

此时试想一个问题:若是try块中new FileInputStream抛出了异常,在finally块中调用close方法时也抛出了异常,那么最终抛给上层的到底是哪一个异常?spa

答案是:抛给上层的是close方法产生的异常。code

可是很明显,咱们但愿的是把catch块中捕获的异常进行处理后,继续向上抛出,可结果却由于close方法产生异常而丢失了咱们预期的异常。对象

针对此问题,解决方案是:调用in.close()时再次使用try-catch块包裹,代码以下:接口

FileInputStream in = null;
		try {
			in = new FileInputStream("d:/in.txt");
		} catch(Exception e) {
			System.out.println(e.getMessage());
			throw new RuntimeException("try块中产生了异常",e);
		} finally {
			if (in != null)
				try {
					in.close();
				}catch(IOException e) {
					e.printStackTrace();
				}
		}

至此,问题已经获得完美解决。可是,每次处理IO问题时都要编码重复且复杂的代码是否是很繁琐?因而,jdk1.7推出了叫作try-with-resources的语法糖。则上面的代码能够改下以下:get

/**
		 * try-with-resource语法糖
		 */
		try (FileInputStream in = new FileInputStream("d:/in.txt")) {
			// do something
		} catch(Exception e) {
			System.out.println("message:"+e.getMessage());
			throw new RuntimeException("try块中产生了异常",e);
		}

try()中的类型必须实现AutoCloseable接口(jdk1.7开始引入了此接口,做为Closeable接口的父接口)。it

此结构的执行顺序为:io

  1. 执行try快中语句class

  2. 调用try()中的全部对象的close()方法

  3. 若是try块产生异常,则执行catch中的逻辑

  4. 若是存在finally块,则执行其逻辑

另外,还须要注意的是:

若是try块产生了异常,则会忽略close产生的异常(若是真的产生异常的话);不然才会抛出close产生的异常(若是真的产生异常的话)。

所以,try-with-resources语法糖等价于如下写法:

        // 此处的try至关于
        // try (FileInputStream in = new FileInputStream("d:/in.txt"))
        try {
            InputStream in = null;
            /**
             * 如下try-catch能够理解为语法糖自动生成的代码
             */
            try {
                in = new FileInputStream("d:/in.txt");
                // do something
                in.close();
            } catch (IOException e) {
                if (in != null)
                    try {
                        in.close();
                    } catch (IOException ee) {
                        if (e != ee)
                            e.addSuppressed(ee);
                    }
                throw e;
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());
            throw new RuntimeException("try块中产生了异常", e);
        }
相关文章
相关标签/搜索