Java 9:改进的Try-With-Resources

Java 7之前

在Java 7之前,在使用一些资源的类时,如BufferedReader,我们要常常提醒自己,必须要在finally块关闭资源。

Java 6示例

BufferedReader br = null;
try {
  br = new BufferedReader(new FileReader("C:\\test.txt"));
  System.out.println(br.readLine());
} catch (IOException e) {
  e.printStackTrace();
} finally {
  try {
    if (br != null)
      br.close();
  } catch (IOException ex) {
    ex.printStackTrace();
  }
}

在Java 6的这个示例里,这段代码有几点不好:

  1. 代码冗长,不可读
  2. 在finally块了还需要对close()方法添加try-catch
  3. 在调用close()前,总要判断Reader是否为null
  4. 如果忘了在finally关闭资源,容易造成资源泄漏

Java 7

Java 7新增了try-with-resoureces自动管理资源的语法。

Java 7示例

try (BufferedReader br = new BufferedReader(new FileReader("C:\\test.txt"))) {
  System.out.println(br.readLine());
} catch (IOException e) {
  e.printStackTrace();
}

这短短的几行代码很优雅地解决了Java 7之前对资源管理存在的问题。 在try()里声明的资源,用户不需要手动关闭资源,它会在用完后自动关闭。这样不需要在关闭资源时的try-catch以及检查资源是否为null,也很好避免了因为忘记关闭资源可能导致的资源泄漏。

Java 7的try-with-resources语法需要符合以下规则:

  1. 资源类需要实现java.lang.AutoCloseable接口
  2. 资源变量必须在try()声明为本地变量。
  3. 如果资源在Try-With-Resources语句外声明,那么必须在try()里使用本地变量引用外部声明的资源变量

以下例子不正确

BufferedReader br = new BufferedReader(new FileReader("C:\\test.txt"))
try (br) {
  System.out.println(br.readLine());
} catch (IOException e) {
  e.printStackTrace();
}

需要改为

BufferedReader br = new BufferedReader(new FileReader("C:\\test.txt"))
try (BufferedReader localReader = br) {   //重新引用为本地变量
  System.out.println(localReader.readLine());
} catch (IOException e) {
  e.printStackTrace();
}

这也算是Java 7/8的Try-With-Resouces bug。

Java 9

Try-With-Resouces在Java 9的改进就是针对Java7/8里资源必须在try()里声明的问题做的修改。

Java 9改进后的Try-With-Resouces允许资源在Try-With-Resouces外部声明,且不需要在try()里重新引用。

BufferedReader reader = new BufferedReader(new FileReader("test.txt"));
 try (reader) {
   System.out.println(reader.readLine());
 }

版权声明:著作权归作者所有。

相关推荐

Java 9数组转换为List

Java 9使用List.of在Java 9,List新增了of()的工厂方法用来产生不可变的列表。返回一个空列表List list = List.of(); 多个元素生成列表List<Integer> list = List.of(1,2,3,4,5); 数组转换为列表Integer[] arr

Java 9的Process和ProcessHandler

Java 9给Process API引入了多种改进,其中新增了ProcessHandler类,它提供了进程相关的信息,如pid,父进程,子进程,进程开始时间以及累计cpu时间等。这里使用Java 9的jshell简单演示下Process的使用:jshell> Process p = new ProcessBuil

Java 9 Stream新增方法takeWhile的bug

Java 9的Stream新增方法takeWile():允许我们返回Stream里满足条件的前面部分元素。如:String[] arr= {"a", "b", "c","d"}; Arrays.stream(arr)     &n

Java 9:List.of()与Arrays.asList()的区别

Java 9新增了List.of的集合工程方法。它与Arrays.asList区别如下:1、Arrays.asList返回的是可变的列表,而List.of返回的是不可变的列表List<Integer> list = Arrays.asList(1, 2, null); list.set(3, 3); //&

理解Java 9的open module(公开模块)

模块化是Java 9新增的一个很重要且影响代码结构的特性。分类根据外部代码在编译时和运行时对模块的访问权限不同分为:常规模块(normal module)和公开模块(open module)。编译时访问比较容易理解,即代码能否显式直接使用模块里的类型,没有权限访问,编译时报错。在运行时访问模块代码是指使用Java里的Core Reflection 

Java 9模块声明中requires and requires transitive的区别

可读性(Readability)首先要理解模块的可读性module bar{     requires drink; } bar requires drink意味着:bar模块强制要求存在drink模块,这称为可靠配置。bar模块可以读入drink模块的文件,这称为可读性。bar模块可以访问drink模块的代码,这称为