我是否正确使用了Java 7的try-with-resources

我期待缓冲的阅读器和文件阅读器closures,并释放资源,如果抛出exception。

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException { try (BufferedReader br = new BufferedReader(new FileReader(filePath))) { return read(br); } } 

但是,是否有要求成功closures的catch条款?

编辑:

从本质上讲,Java 7中的上述代码等同于下面的Java 6:

 public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException { BufferedReader br = null; try { br = new BufferedReader(new FileReader(filePath)); return read(br); } catch (Exception ex) { throw ex; } finally { try { if (br != null) br.close(); } catch(Exception ex) { } } return null; } 

这是正确的,并没有要求catch语句。 Oracle java 7 doc表示, 无论是否实际抛出exception,资源都将被closures。

只有当你想对exception作出反应时,你才应该使用catch子句。 catch子句将在资源closures执行。

以下是Oracle教程的一个片段:

以下示例从文件读取第一行。 它使用BufferedReader的实例从文件中读取数据。 BufferedReader是程序完成后必须closures的资源:

 static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } } // In this example, the resource declared in the try-with-resources statement is a BufferedReader. 

…因为BufferedReader实例是在try-with-resource语句中声明的,所以无论try语句是正常还是突然完成(由于BufferedReader.readLine抛出一个IOException),它都将被closures。

编辑

关于新编辑的问题:

Java 6中的代码执行catch和之后的finally块。 这导致资源仍然可能在catch块中打开。

在Java 7语法中,资源在catch之前closures,因此资源在catch块执行期间已经closures。 这在上面的链接中有logging:

在try-with-resources语句中,声明的资源closures后,将运行任何catch或finally块。

在这种特殊情况下,您对资源尝试的使用可以很好地工作,但总的来说这是不正确的。 你不应该像这样链接资源,因为它可能会导致不愉快的意外。 假设你有一个可变的缓冲区大小:

 public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException { int sz = /* get buffer size somehow */ try (BufferedReader br = new BufferedReader(new FileReader(filePath), sz)) { return read(br); } } 

假设出了问题,你最终以sz为负。 在这种情况下,您的文件资源(通过new FileReader(filePath)创build) 不会被closures。

为了避免这个问题,你应该像这样分别指定每个资源:

 public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException { int sz = /* get buffer size somehow */ try (FileReader file = new FileReader(filePath); BufferedReader br = new BufferedReader(file, sz)) { return read(br); } } 

在这种情况下,即使初始化失败file仍然closures。 你可以在这里和这里find更多的细节。