【问题标题】:Using finally keyword on InputStream#close()在 InputStream#close() 上使用 finally 关键字
【发布时间】:2014-03-23 13:02:06
【问题描述】:

基本上我不确定finally关键字的正确用法是什么,我只知道文本定义:保证代码将被执行,因为有时它不会。所以我希望我能得到一些关于这个特定代码的指导:

如果 try-catch 块调用 InputStream#close() 是不必要的

try {
    inputStream = entity.getContent();

    BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
    StringBuilder sb = new StringBuilder();

    String line = null;

    while((line = br.readLine()) != null) {
        sb.append(line);
        sb.append("\n");
    }

    responseText = sb.toString();
} catch(IOException e) {
    e.printStackTrace();
} finally {
    if (inputStream != null) {
        try {
            inputStream.close();
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}

【问题讨论】:

  • 这段代码是 Apache HttpClient 的吗? (那个 entity.getContent() 看起来很眼熟!)如果是这样,请尝试使用 EntityUtils.consume(entity) 来确保释放连接。
  • 是的。我试试看

标签: java inputstream ioexception try-catch-finally


【解决方案1】:

您也可以使用try-with-resources

像这样:

try (YourResource resource) {
    //Todo...
} catch(YourSpecificException ex) {
    //Todo...
}

您在括号之间声明的资源将在退出构造时自动关闭。

您甚至可以一次声明多个资源,用分号分隔它们。真的都在上面的链接里。

【讨论】:

  • 我不是Pokémon Exception Handling 的粉丝。抓住抛出的东西,让实际的错误冒出来。
  • @DavidEhrmann 如果您指的是通用异常,那么您是完全正确的,我同意。我只是把它作为一个通用的例子放在那里。事后看来,它可能发出了错误的信号。让我编辑一下。
【解决方案2】:

finally 块将始终执行,无论异常是否来自 try 块。因此,finally 块用作发布活动。在您用于关闭流的代码中。

【讨论】:

    【解决方案3】:

    finally 块确保无论在尝试期间发生什么(成功或异常),它都会始终运行。这通常在清理资源时使用,例如 InputStreamSocket

    try with resource 范式会清除此问题,但会自动关闭 Closeable 的内容

    try( InputStream inputStream = entity.getContent() )
    {
    
    }catch(Exception e)
    {
    
    }//declared resource in try automatically closed
    

    http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

    【讨论】:

      【解决方案4】:

      try 块正在执行时,发生的任何异常都会将执行转移到catch 块然后到finally 块但是如果在尝试中没有发生异常,则代码的执行将在尝试到finally 块,在您的代码中,您正在尝试使用 IO 资源,如果它不能被进程占用,则可能会引发 IO 异常,那么不会将引用分配给inputStream 必须找到 finally 块才能关闭 IO 连接在任何情况下,如果资源被占用或者如果它为 null 则什么都没有,记住 finally 总是会在任何情况下执行,有时最好关闭与数据库和其他资源的连接以释放内存。

      【讨论】:

        【解决方案5】:

        我最后使用的次数一般是……

        • 资源处理(IO、数据库连接、套接字)
        • 并发(锁释放,保证计数器更改)
        • 最终确定 (try { } finally { super.finalize(); })
        • 状态记录保存

        【讨论】:

          【解决方案6】:
          try { 
            // Here the guarded area starts
          
          
            // Here the guarded area ends
          } catch {
            // This block is executed when an exception occurs inside the guarded area
          
          } finally {
            // This block is executed always before leaving try - catch - finally block
            // If there is an exception, then first catch block is executed and then finally
          }
          

          finally 块内的代码是关闭流的常用结构。如果在受保护区域 (inputStream != null) 内创建了流,则 finally 块将关闭它。如果在inputStream创建之前有异常,那么finally块会被执行,但是因为inputStream == nullif语句里面的代码不会执行。

          【讨论】:

            猜你喜欢
            • 2017-05-27
            • 2019-12-07
            • 2017-12-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-09-20
            • 1970-01-01
            • 2013-09-24
            相关资源
            最近更新 更多