标签: try-with-resources

在try-with-resources块中管理多个链式资源的正确习惯用法?

当仅使用一个资源时,Java 7 try-with-resources语法(也称为ARM块(自动资源管理))很好,简短而直接AutoCloseable.但是,当我需要声明彼此依赖的多个资源时,我不确定什么是正确的习惯用法,例如a FileWriter和a BufferedWriter包装它.当然,这个问题涉及AutoCloseable包装某些资源的任何情况,而不仅仅是这两个特定的类.

我提出了以下三种选择:

1)

我见过的天真的习惯是只声明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 将不会被关闭.

2)

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)

java try-with-resources

163
推荐指数
3
解决办法
3万
查看次数

我应该如何在JDBC中使用try-with-resources?

我有一种方法可以使用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)

java jdbc java-7 try-with-resources

135
推荐指数
4
解决办法
10万
查看次数

在Kotlin尝试资源

当我尝试在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)

extension-methods try-with-resources kotlin

133
推荐指数
3
解决办法
2万
查看次数

我是否正确使用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);
    } 
}
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)

java-7 try-with-resources

86
推荐指数
2
解决办法
6万
查看次数

什么是被抑制的异常?

注释(用户SOC上的)回答关于尾调用优化的问题提到了Java 7中有一个称呼,是因为"加ARM的"的"抑制异常",新的功能(适用于ARM CPU的支持?).

在这种情况下,什么是"抑制异常"?在其他情况下,"被抑制的异常"将是一个被捕获然后被忽略的异常(很少是一个好主意); 这显然是不同的.

java exception-handling exception try-with-resources

66
推荐指数
5
解决办法
5万
查看次数

有资源尝试的8个分支机构 - 可能覆盖jacoco吗?

我有一些代码使用try资源和jacoco它只有一半覆盖.所有的源代码行都是绿色的,但我得到一个黄色的小符号告诉我8个分支中只有4个被覆盖.

在此输入图像描述

我无法弄清楚所有分支是什么,以及如何编写涵盖它们的代码.扔三个可能的地方PipelineException.这些createStageList(),processItem()以及隐含的close()

  1. 没有抛出任何例外,
  2. 抛出异常 createStageList()
  3. 抛出异常 processItem()
  4. 抛出异常 close()
  5. processItem()和抛出异常close()

我想不出任何其他情况,但我仍然只有8个中有4个被覆盖.

有人可以向我解释为什么它是8中的4,并且无论如何都可以击中所有8个分支?我不熟悉decyrpting /阅读/解释字节码,但也许你是...... :)我已经看过https://github.com/jacoco/jacoco/issues/82,但它既不是也不是问题它非常引用帮助(除了注意这是由于编译器生成的块)

嗯,就在我写完这篇文章的时候,我想到了上面提到的那些案例可能没有被测试过......如果我做对了,我会发一个答案.我确信这个问题和答案在任何情况下都会对某人有所帮助.

编辑:没有,我没有找到它.抛出RuntimeExceptions(不由catch块处理)不包括任何更多分支

java code-coverage bytecode try-with-resources jacoco

60
推荐指数
4
解决办法
2万
查看次数

为什么try-with-resource需要一个局部变量?

参考我的问题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)

java try-with-resources

57
推荐指数
3
解决办法
9581
查看次数

使用AutoCloseable关闭多个资源(尝试使用资源)

我知道,如果资源实现了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

54
推荐指数
3
解决办法
5万
查看次数

使用Try-Catch with Resources时,IntelliJ IDE会出错

我试图使用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

49
推荐指数
4
解决办法
3万
查看次数

使用新的try-with-resources块在SQLException上进行事务回滚

我在尝试使用资源时遇到问题,我要求确定一下.我是否可以使用它,如果我需要对异常做出反应,我仍然需要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块都在资源之后运行声明已关闭."

java try-with-resources

43
推荐指数
4
解决办法
3万
查看次数