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

首先回忆一下jdk1.7之前,我们要通过流读取文件时,代码要怎样写?

假设本地文件系统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方法时也抛出了异常,那么最终抛给上层的究竟是哪个异常?

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

但是很明显,我们希望的是把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的语法糖。则上面的代码可以改下如下:

/**
		 * 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接口的父接口)。

此结构的执行顺序为:

  1. 执行try快中语句

  2. 调用try()中的所有对象的close()方法

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

  4. 如果存在finally块,则执行其逻辑

另外,还需要注意的是:

如果try块产生了异常,则会忽略close产生的异常(如果真的产生异常的话);否则才会抛出close产生的异常(如果真的产生异常的话)。

因此,try-with-resources语法糖等价于以下写法:

未完待续。。。

你可能感兴趣的:(jdk1.7中try-with-resources语法糖详解)