今天在写Jdbc操作的时候,关于资源关闭那部分代码,发现了一个接口类AutoCloseable
跟我之前的写法不太一样,顺便拿出来研究一下。
背景
用Java写代码时遇到文件操作、Connection
连接操作等,操作完毕之后必然要资源关闭,之前我都是手动关闭的。但是现在碰到AutoCloseable
,从名字上看也能看出这是自动关闭,那不是很方面我们写代码了嘛!
发现
写Jdbc操作的时候,基本都是需要用到PreparedStatement
、Connection
等类的,那这些类是需要关闭的。我根据老旧的代码思维写了一个通用的关闭方法。
/**
* 关闭资源
* @param args 需关闭的资源
*/
public void close(Closeable...args) {
if(args!=null && args.length > 0){
for(Closeable a:args){
if(a!=null){
try {
a.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
然后在我在finally
代码块中使用了
...
close(preparedStatement,resultSet);
但是这样竟然报错了,close
方法的参数不对,我就点进去看了一个原来现在PreparedStatement
、Connection
等类都是继承AutoCloseable
,时代不一样了,我的代码思维老了。那就研究一下。
/*
* @author Josh Bloch
* @since 1.7
*/
public interface AutoCloseable {
void close() throws Exception;
}
这个类是从jdk1.7加入的。类里有很多解释,大概意思就是使用try-with-resources
能够自动关闭资源,这种结构能够确保及时释放资源,避免资源耗尽异常和错误的发生。当程序抛出异常时能自动调用close
方法进行资源释放,当没有抛出异常正常退出try-block
时候也会调用close
方法。
测试
public interface IMessage extends AutoCloseable {
void sendMessage(String message);
void close() throws Exception;
}
public class NetMessage implements IMessage {
public NetMessage(){
System.out.println("[服务器建立了连接...]");
}
@Override
public void sendMessage(String message) {
//throw new RuntimeException("发生了异常,与服务器断掉了");
System.out.println("[服务器正在发送信息===>"+message+"]");
}
@Override
public void close() throws Exception {
System.out.println("[服务器关闭了...]");
}
}
public class AutoCloseableTest {
@Test
public void test(){
try(NetMessage netMessage = new NetMessage()){
netMessage.sendMessage("Hello World");
}catch (Exception e){
System.out.println("发生了异常==>"+e.getMessage());
}
}
}
当程序成功退出try-block
时,结果为
[服务器建立了连接...]
[服务器正在发送信息===>Hello World]
[服务器关闭了...]
如果程序抛出了异常,结果为
[服务器建立了连接...]
[服务器关闭了...]
发生了异常==>发生了异常,与服务器断掉了
程序很清楚明了的AutoCloseable
的作用了。
总结
- 使用
try-catch-resources
的方式,不管是否正常执行程序,close方法都是能够正常调用的。 - 只用在
try
的()中声明的资源的close
方法才会被调用。 - 使用
try-catch-resources
结构,无须显示调用资源释放。