Try-with-resources:我必须抛出或捕获 close() 方法的异常吗? [复制]
Posted
技术标签:
【中文标题】Try-with-resources:我必须抛出或捕获 close() 方法的异常吗? [复制]【英文标题】:Try-with-resources: Must I throw or catch the close() method's exceptions? [duplicate] 【发布时间】:2013-04-09 06:53:46 【问题描述】:如果有错误,请纠正我:在 Java 7 的 try-with-resources 语句中,资源的 close()
方法抛出的任何异常都必须声明为由我的方法抛出,或者我必须将整个尝试包装在另一个 @ 987654322@ 捕获close()
抛出的任何异常。
如果是这样,我想知道我是否会充分利用它。我当然不想throw
close()
抛出的异常,调用者不知道该怎么办。一个 try
包裹另一个 try
只是为了处理 close()
看起来不是很优雅,至少对我来说。
编辑:我想我不小心问了两个问题,其中一个是重复的。
问题 1. 我是否必须声明我的方法从 close()
方法抛出异常或将 try-with-resources 包装在另一个尝试中? (建议的副本中没有回答。)
问题2.有没有办法静默关闭资源? (显然是重复的,所以我把这句话排除在问题之外。希望这能让这个问题令人满意地独一无二。)
【问题讨论】:
你有很多资源从close()
扔过来的吗?
只有几个,但我经常使用它们(ResultSet、BufferedReader、RandomAccessFile)。
【参考方案1】:
引用Java Language Specification ($14.20.3.2):
14.20.3.2 扩展的 try-with-resources
带有至少一个 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 子句 捕获由于任何资源的自动初始化或关闭而导致的异常。
所以,基本上,包装器已经实现了
【讨论】:
【参考方案2】:来自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().
【讨论】:
如果不调用catch并且没有finally块,资源会被关闭吗? 点击链接阅读。 这种方法并不能解决问题。对我来说,“正常”行为是:1)从 readLine 重新抛出异常 2)忽略 close 抛出的异常。按照您建议的方式进行操作,没有一种简单的方法可以知道异常是来自 readLine 还是来自 close。【参考方案3】:您不需要将 try-with-resources 包装在另一个 try-catch 块中,只需添加一个 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();
【讨论】:
【参考方案4】:您应该能够简单地添加适当的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 子句中放置多个异常,或者您可以简单地捕获所需的最外层异常。
【讨论】:
以上是关于Try-with-resources:我必须抛出或捕获 close() 方法的异常吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
try-with-resources 或 close() 困境
1.9 try-with-resources 优先于try-finally
谁在 close 方法中捕获异常?(try-with-resources)