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

时间:2013-07-15 09:32:45

标签: java-7 try-with-resources

我期待缓存的读取器和文件读取器关闭,如果抛出异常,则释放资源。

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

但是,是否要求成功关闭一个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;
}

2 个答案:

答案 0 :(得分:100)

这是正确的,并且不需要catch子句。 Oracle java 7 doc说,无论是否实际抛出异常,资源都将被关闭

只有在想要对异常作出反应时才应使用catch子句。 资源关闭后,将执行catch子句。

以下是Oracle's tutorial的摘录:

  

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

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实例是在a中声明的   try-with-resource语句,无论是否,它都将被关闭   try语句正常或突然完成(由于   方法BufferedReader.readLine抛出IOException)。

修改

关于新编辑的问题:

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

在Java 7语法中,资源在 catch块之前关闭,因此在catch块执行期间资源已经关闭。这在以上链接中有记录:

  

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

答案 1 :(得分:68)

在这种特殊情况下,你对try-with-resources的使用会很好,但总的来说它并不完全正确。你不应该链接这样的资源,因为它可能会导致令人不快的意外。假设您有一个可变缓冲区大小:

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)创建)将 NOT 关闭。

要避免此问题,您应该单独指定每个资源:

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);
    } 
}

在这种情况下,即使br的初始化失败file仍然关闭。您可以找到更多详细信息herehere