当仅使用一个资源时,Java 7 try-with-resources语法(也称为ARM块(自动资源管理))很好,简短而直接AutoCloseable.但是,当我需要声明彼此依赖的多个资源时,我不确定什么是正确的习惯用法,例如a FileWriter和a BufferedWriter包装它.当然,这个问题涉及AutoCloseable包装某些资源的任何情况,而不仅仅是这两个特定的类.
我提出了以下三种选择:
我见过的天真的习惯是只声明ARM管理变量中的顶级包装器:
static void printToFile1(String text, File file) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
bw.write(text);
} catch (IOException ex) {
// handle ex
}
}
Run Code Online (Sandbox Code Playgroud)
这很好而且简短,但它已被打破.由于底层FileWriter未在变量中声明,因此永远不会在生成的finally块中直接关闭它.它只能通过close包装方法关闭BufferedWriter.问题是,如果从bw构造函数抛出异常,close则不会调用它,因此底层FileWriter 将不会被关闭.
static void printToFile2(String text, File file) {
try (FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw)) {
bw.write(text); …Run Code Online (Sandbox Code Playgroud) 我有一种方法可以使用JDBC从数据库中获取用户:
public List<User> getUser(int userId) {
String sql = "SELECT id, name FROM users WHERE id = ?";
List<User> users = new ArrayList<User>();
try {
Connection con = DriverManager.getConnection(myConnectionURL);
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, userId);
ResultSet rs = ps.executeQuery();
while(rs.next()) {
users.add(new User(rs.getInt("id"), rs.getString("name")));
}
rs.close();
ps.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
return users;
}
Run Code Online (Sandbox Code Playgroud)
我应该如何使用Java 7 try-with-resources来改进此代码?
我已尝试使用下面的代码,但它使用了许多try块,并且不会提高可读性.我应该try-with-resources以其他方式使用吗?
public List<User> getUser(int userId) {
String sql = "SELECT id, name …Run Code Online (Sandbox Code Playgroud) 当我尝试在Kotlin中编写相当于try-with-resources的代码时,它对我不起作用.
我尝试了以下不同的变体:
try (writer = OutputStreamWriter(r.getOutputStream())) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
但都不起作用.
有谁知道应该使用什么?显然Kotlin语法没有这种结构的定义,但可能是我遗漏了一些东西.它定义了try块的语法,如下所示:
try : "try" block catchBlock* finallyBlock?;
Run Code Online (Sandbox Code Playgroud) 我期待缓存的读取器和文件读取器关闭,如果异常抛出则释放资源.
public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
try (BufferedReader br = new BufferedReader(new FileReader(filePath)))
{
return read(br);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,是否需要有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;
}
Run Code Online (Sandbox Code Playgroud) 注释(用户SOC上的)回答到关于尾调用优化的问题提到了Java 7中有一个称呼,是因为"加ARM的"的"抑制异常",新的功能(适用于ARM CPU的支持?).
在这种情况下,什么是"抑制异常"?在其他情况下,"被抑制的异常"将是一个被捕获然后被忽略的异常(很少是一个好主意); 这显然是不同的.
我有一些代码使用try资源和jacoco它只有一半覆盖.所有的源代码行都是绿色的,但我得到一个黄色的小符号告诉我8个分支中只有4个被覆盖.

我无法弄清楚所有分支是什么,以及如何编写涵盖它们的代码.扔三个可能的地方PipelineException.这些createStageList(),processItem()以及隐含的close()
createStageList()processItem()close()processItem()和抛出异常close()我想不出任何其他情况,但我仍然只有8个中有4个被覆盖.
有人可以向我解释为什么它是8中的4,并且无论如何都可以击中所有8个分支?我不熟悉decyrpting /阅读/解释字节码,但也许你是...... :)我已经看过https://github.com/jacoco/jacoco/issues/82,但它既不是也不是问题它非常引用帮助(除了注意这是由于编译器生成的块)
嗯,就在我写完这篇文章的时候,我想到了上面提到的那些案例可能没有被测试过......如果我做对了,我会发一个答案.我确信这个问题和答案在任何情况下都会对某人有所帮助.
编辑:没有,我没有找到它.抛出RuntimeExceptions(不由catch块处理)不包括任何更多分支
参考我的问题java.util.concurrent.locks.Lock的AutoCloseable包装中的任何风险?,我想知道为什么trh try-with-resource需要一个命名的局部变量.
我目前的用法如下:
try (AutoCloseableReentrantReadWiteLock.Lock l = _lock.writeLock()) {
// do something
}
Run Code Online (Sandbox Code Playgroud)
该变量l在try块内未使用,仅污染命名空间.从我记忆中的类比C# using语句不需要本地命名变量.
是否有任何理由无法支持以下内容,并且在try块结束时关闭了一个匿名局部变量?
try (_lock.writeLock()) {
// do something
}
Run Code Online (Sandbox Code Playgroud) 我知道,如果资源实现了AutoCloseable,那么您通过try传递的资源将自动关闭.到现在为止还挺好.但是当我有几个我希望自动关闭的资源时,该怎么办?套接字示例;
try (Socket socket = new Socket()) {
input = new DataInputStream(socket.getInputStream());
output = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
}
Run Code Online (Sandbox Code Playgroud)
所以我知道套接字将被正确关闭,因为它在try中作为参数传递,但输入和输出应如何正确关闭?
java sockets datainputstream try-with-resources autocloseable
我试图使用JDK 7的"try-catch with resources"声明; IntelliJ强调我的资源线,说
此语言级别不支持尝试使用资源.
当我尝试编译时,我得到:
java:在-source 1.6中不支持try-with-resources(使用-source 7或更高版本来启用try-with-resources)
我检查了我的当前项目是否启用了try-with-resources,我的项目是使用JDK 7(Library:C:\ Program Files\Java\jdk1.7.0_11).有任何想法吗?我无法弄清楚要改变什么选项(如果这甚至是问题).
java try-catch intellij-idea try-catch-finally try-with-resources
我在尝试使用资源时遇到问题,我要求确定一下.我是否可以使用它,如果我需要对异常做出反应,我仍然需要catch块中的资源?给出的例子如下:
try (java.sql.Connection con = createConnection())
{
con.setAutoCommit(false);
Statement stm = con.createStatement();
stm.execute(someQuery); // causes SQLException
}
catch(SQLException ex)
{
con.rollback();
// do other stuff
}
Run Code Online (Sandbox Code Playgroud)
我担心在这种情况下,我仍然注定要使用旧的try-catch-finally,即使根据oracle文档 - "在try-with-resources语句中捕获并最终阻塞,任何catch或finally块都在资源之后运行声明已关闭."