如何使用try-with-resource机制关闭连接

使用try-with-resource机制关闭连接

JAVA的一大特性就是JVM会对内部资源实现自动回收

即自动GC,给开发者带来了极大的便利。但是JVM对外部资源的引用却无法自动回收,例如数据库连接,网络连接以及输入输出IO流等,这些连接就需要我们手动去关闭,不然会导致外部资源泄露,连接池溢出以及文件被异常占用等。

传统的手动释放外部资源一般放在

try{}catch(){}finally{}机制的finally代码块中,因为finally代码块中语句是肯定会被执行的,即保证了外部资源最后一定会被释放。同时考虑到finally代码块中也有可能出现异常,finally代码块中也有一个try{}catch(){},这种写法是经典的传统释放外部资源方法,显然是非常繁琐的。

JDK1.7之后有了try-with-resource处理机制

首先被自动关闭的资源需要实现Closeable或者AutoCloseable接口,因为只有实现了这两个接口才可以自动调用close()方法去自动关闭资源。写法为try(){}catch(){},将要关闭的外部资源在try()中创建,catch()捕获处理异常。

其实try-with-resource机制是一种语法糖,其底层实现原理仍然是try{}catch(){}finally{}写法,不过在catch(){}代码块中有一个addSuppressed()方法,即异常抑制方法。

如果业务处理和关闭连接都出现了异常,业务处理的异常会抑制关闭连接的异常,只抛出处理中的异常,仍然可以通过getSuppressed()方法获得关闭连接的异常。

和传统的try{}catch(){}finally{}机制相比,try-with-resource处理机制有了这个异常抑制方法就是帮助我们简化了关闭连接时出现异常的处理。

try-with-resource使用时遇到的问题

java 1.7之后 增加了 try-wit-resource的语法糖

大概的用法就是在try中声明一个或者多个的流,会在try块代码执行完成后自动关闭流,不用再写finally进行手都关闭。

try (InputStream is1 = ...;
     InputStream is2 = ...;) {
    //do something
} catch{
}

于是我就在项目中想改成这种写法,但是在改的过程中遇到了一些问题。我的代码中需要对声明过后的流再赋值,但是用这样的写法一直会报错

代码大概是这样的:

此时会编译出错:

The resource is1 of a try-with-resources statement cannot be assigned;

报错的原因是:

try-with-source中声明的变量无法被更改。但是我很奇怪这是为什么,上网搜了没有搜到,于是去找了一下官方文档。官方文档中有一段这样的描述:

It is a compile-time error if final appears more than once as a modifier for each variable declared in a resource specification. A variable declared in a resource specification is implicitly declared final (§4.12.4) if it is not explicitly declared final.

意思就是,try-with-resource中声明的变量会隐式的加上final 关键字,所以无法再进行赋值。但是至于为什么这么设计,我暂时没找到答案。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Java使用 try-with-resources 实现自动关闭资源的方法

    1. 在Java1.7之前,我们需要通过下面这种方法, 在finally中释放资源,这种方法有点繁琐. BufferedReader br = null; String str; try { br = new BufferedReader(new FileReader("")); while ((str = br.readLine()) != null) { System.out.println(str); } } catch (IOException e) { e.printStac

  • Java try-with-resource语法使用解析

    背景 众所周知,所有被打开的系统资源,比如流.文件或者Socket连接等,都需要被开发者手动关闭,否则随着程序的不断运行,资源泄露将会累积成重大的生产事故. 在Java的江湖中,存在着一种名为finally的功夫,它可以保证当你习武走火入魔之时,还可以做一些自救的操作.在远古时代,处理资源关闭的代码通常写在finally块中.然而,如果你同时打开了多个资源,那么将会出现噩梦般的场景: public class Demo { public static void main(String[] arg

  • Java如何优雅地关闭资源try-with-resource及其异常抑制

    一.背景 我们知道,在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们.因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制,如果我们不在编程时确保在正确的时机关闭外部资源,就会导致外部资源泄露,紧接着就会出现文件被异常占用,数据库连接过多导致连接池溢出等诸多很严重的问题.  二.传统的资源关闭方式 为了确保外部资源一定要被关闭,通常关闭代码被写入finally代码块中,当然我们还必须注意到关闭资源时可能抛出的异常,于是变

  • try-with-resource优雅关闭io流的方法

    前言 JAVA的一大特性就是JVM会对内部资源实现自动回收,即自动GC,给开发者带来了极大的便利.但是JVM对外部资源的引用却无法自动回收,例如数据库连接,网络连接以及输入输出IO流等,这些连接就需要我们手动去关闭,不然会导致外部资源泄露,连接池溢出以及文件被异常占用等. 传统的手动释放外部资源一般放在一般放在try{}catch(){}finally{}机制的finally代码块中,因为finally代码块中语句是肯定会被执行的,即保证了外部资源最后一定会被释放.同时考虑到finally代码块

  • 如何使用try-with-resource机制关闭连接

    使用try-with-resource机制关闭连接 JAVA的一大特性就是JVM会对内部资源实现自动回收 即自动GC,给开发者带来了极大的便利.但是JVM对外部资源的引用却无法自动回收,例如数据库连接,网络连接以及输入输出IO流等,这些连接就需要我们手动去关闭,不然会导致外部资源泄露,连接池溢出以及文件被异常占用等. 传统的手动释放外部资源一般放在 try{}catch(){}finally{}机制的finally代码块中,因为finally代码块中语句是肯定会被执行的,即保证了外部资源最后一定

  • PHP中PDO关闭连接的方法问题

    在之前我们手写 mysql 的连接操作时,一般都会使用 mysql_close() 来进行关闭数据库连接的操作.不过在现代化的开发中,一般使用框架都会让我们忽视了底层的这些封装,而且大部分框架都已经默认是使用 PDO 来进行数据库的操作,那么,大家知道 PDO 是如何关闭数据的连接的吗? 官方说明 要想关闭连接,需要销毁对象以确保所有剩余到它的引用都被删除,可以赋一个 NULL 值给对象变量.如果不明确地这么做,PHP 在脚本结束时会自动关闭连接. $pdo = new PDO('mysql:h

  • PHP操作mysql函数详解,mysql和php交互函数

    1. 建立和关闭连接 1) mysql_connect() resource mysql_connect([string hostname [:port][:/path/to/socket][,string username] [,string password]]) 所有参数都是可选的 举例: @mysql_connect("localhost", "user", "password") or die("Could not conne

  • .net 中的SqlConnection连接池机制详解

    正确的理解这个连接池机制,有助于我们编写高效的数据库应用程序. 很多人认为 SqlConnection 的连接是不耗时的,理由是循环执行 SqlConnection.Open 得到的平均时间几乎为0,但每次首次open 时,耗时又往往达到几个毫秒到几秒不等,这又是为什么呢? 首先我们看一下 MSDN 上的权威文档上是怎么说的 Connecting to a database server typically consists of several time-consuming steps. A

  • 探究Android客户端网络预连接优化机制

    目录 一.连接复用 二.预连接实现 三.源码分析 四.优化 五.问答 一.连接复用 对于一个普通的接口请求,通过charles抓包,查看网络请求Timing栏信息,我们可以看到类似如下请求时长信息: Duration 175 ms DNS 6 ms Connect 50 msTLS Handshake 75 ms Request 1 ms Response 1 ms Latency 42 ms 同样的请求,再来一次,时长信息如下所示: Duration 39 ms DNS - Connect -

  • socket连接关闭问题分析

    socket编程过程中往往会遇到这样那样的问题,出现了这些问题,有的是由于并发访问量太大造成的,有些却是由于代码中编程不慎造成的.比如说,最常见的错误就是程序中报打开的文件数过多这个错误.socket建立连接的时候是三次握手,这个大家都很清楚,但是socket关闭连接的时候,需要进行四次挥手,但很多人对于这四次挥手的具体流程不清楚,吃了很多亏. CLOSE_WAIT分析 socket是一种全双工的通信方式,建立完socket连接后,连接的任何一方都可以发起关闭操作.这里不妨假设连接的关闭是客户端

  • HttpClient连接池及重试机制解析

    目录 一.HttpClient 简介 功能介绍 使用方法 二.HttpClientUtil 2.1HttpClient版本 2.2项目中用到的工具类如下 2.3笔者着重说一下http连接池 三.HttpClient的重试机制 3.1.那么问题来了HttpClient有没有重试策略? 3.2执行流程 3.3关闭重试 四.总结 4.1重试发生的条件 4.2不发生重试的异常 4.3实践中遇到的异常 一.HttpClient 简介 HttpClient 是Apache Jakarta Common 下的

  • PHP中用mysqli面向对象打开连接关闭mysql数据库的方法

    如下所示: 代码如下: <meta http-equiv="content-type" content="text/html" charset="utf-8"/> <h1>用mysqli面向对象方法连接数据库!-姚远的博客</h1> <form method="POST" action="<?php echo htmlspecialchars($_SERVER['PHP

  • 详细解读Hibernate的缓存机制

    一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据. 二.what(Hibernate缓存原理是怎样的?)Hibernate缓存包括两大类:Hibernate一级缓存和Hibernate二级缓存. 1.Hibernate一级缓存又称为"Session的

  • ASP.NET 6种常用数据库的连接方法

    1.C#连接连接Access 程序代码:     复制代码 代码如下: using   System.Data; using   System.Data.OleDb;    .. string   strConnection="Provider=Microsoft.Jet.OleDb.4.0;";     strConnection+=@"Data   Source=C:BegASPNETNorthwind.mdb"; OleDbConnection   objCo

随机推荐