尝试使用资源:我必须抛出或捕获close()方法的异常吗?

时间:2013-04-09 06:53:46

标签: java exception-handling

如果这是错误的,请纠正我:在Java 7的try-with-resources语句中,资源的close()方法抛出的任何异常都必须声明为我的方法抛出,或者我必须将整个尝试包装起来另一个try可以捕获close()引发的任何异常。

如果是这样,我不得不怀疑我是否会对它有很多用处。我当然不希望throw close()引发的异常,调用者不知道该怎么做。而try包裹另一个try只是为了处理close()对我来说看起来不会很优雅。

编辑:我想我不小心问了两个问题,其中一个是重复的。

问题1.我是否必须声明我的方法从close()方法抛出异常或在另一次尝试中包装try-with-resources? (未在拟议的副本中回答。)

问题2.有没有办法以静默方式关闭资源? (显然是重复的,所以我不接受这个句子。希望这使得这个问题令人满意地独特。)

4 个答案:

答案 0 :(得分:31)

引自Java Language Specification ($14.20.3.2)

  

14.20.3.2扩展资源试用

     

带有至少一个catch子句和/或finally的 try-with-resources 语句   子句称为扩展的try-with-resources语句。   扩展的try-with-resources语句的含义:

     

尝试 ResourceSpecification
  块
  捕捞量 <子> 选择
  最后 <子> 选择

     

通过以下翻译给出基本的 try-with-resources 语句   (§14.20.3.1)嵌套在 try-catch try-finally try-catch-finally 中   语句:

     

尝试{
  尝试 ResourceSpecification
  块
  }
  捕捞量 <子> 选择
  最后 <子> 选择

     

翻译的效果是将ResourceSpecification置于“try”内部   声明。这允许扩展的try-with-resources语句的catch子句   由于自动初始化或关闭任何资源而捕获异常。   

所以,基本上,包装器已经实现了

答案 1 :(得分:22)

来自the Java tutorial

  

try-with-resources语句可以像普通的try语句一样有catch和finally块。在try-with-resources语句中,在声明的资源关闭后运行任何catch或finally块

(强调我的)

所以你可以简单地做

try (BufferedReader br =
               new BufferedReader(new FileReader(path))) {
    return br.readLine();
}
catch (IOException e) {
    // handle the exception that has been thrown by readLine() OR by close().
}

答案 2 :(得分:7)

您不需要在另一个try-catch块中包装try-with-resources,只需添加一个catch块:

class Foo implements AutoCloseable {
    public void close() throws Exception {
        throw new Exception();
    }
}

public class Try {
    public static void main(final String[] args) {
        try(Foo f = new Foo()) {
            System.out.println("No op!");
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

答案 3 :(得分:2)

您应该能够简单地添加适当的catch (Exception e) { }子句。如果你需要对特定的一个进行特殊处理,或者你可以简单地捕捉Exception,如果你需要它更广泛。

try (Statement stmt = con.createStatement()) {
    ResultSet rs = stmt.executeQuery(query);

    while (rs.next()) {
        String coffeeName = rs.getString("COF_NAME");
        int supplierID = rs.getInt("SUP_ID");
        float price = rs.getFloat("PRICE");

        System.out.println(coffeeName + ", " + supplierID + ", " + 
                           price + ", " + sales + ", " + total);
    }
} catch (Exception e) {
    System.out.println("Exception while trying to through the queries. ", e);
}

由于它是Java 7,你实际上可以为每个catch子句放置多个异常,或者你可以简单地捕获你想要的最外层异常。