Java正常关闭资源的方式
在实际开发中,经常需要在程序中打开一些物理资源,如数据库连接、网络连接、磁盘文件等,打开这些物理资源之后必须显式关闭,否则将会引起资源泄漏。
JVM的垃圾回收机制不会回收这些资源,垃圾回收机制属于Java内存管理的一部分,它只是负责回收堆内存中分配出来的内存,至于程序中打开的物理资源,垃圾回收机制是无能为力的。
为了正常关闭程序中打开的物理资源,应该使用finally块来保证回收。
下面程序示范了常见的数据库资源。
importjava.sql.Connection;
importjava.sql.DriverManager;
importjava.sql.PreparedStatement;
importjava.sql.ResultSet;
importjava.sql.SQLException;
public class Tester {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "root";
Connection conn = null;
PreparedStatement pst = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url,user, password);
pst = conn.prepareStatement("select* from test");
rs = pst.executeQuery();
while (rs.next()) {
System.out.println(rs.getObject(0));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
rs.close();
pst.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
虽然程序已经使用finally块来保证资源被关闭,但是这个程序的关闭是不安全的。因为程序开始时指定conn = null;pst = null;rs = null;,完全有可能在程序运行过程中初始化conn之前就引发了异常,那么conn、pst、rs还未来得及初始化,因此它们根本无需关闭。
将上面程序改为如下形式:
importjava.sql.Connection;
importjava.sql.DriverManager;
importjava.sql.PreparedStatement;
importjava.sql.ResultSet;
importjava.sql.SQLException;
public class Tester {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "root";
Connection conn = null;
PreparedStatement pst = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url,user, password);
pst = conn.prepareStatement("select* from test");
rs = pst.executeQuery();
while (rs.next()) {
System.out.println(rs.getObject(0));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(rs != null){
rs.close();
}
if(pst != null){
pst.close();
}
if(conn != null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
程序首先保存rs不为null才关闭,再保证pst不为null才关闭pst,再保证conn不为null才关闭conn。
这样表面看起来安全,实际上并不是这样。假如程序开始已经正常初始化了conn、pst、rs,在关闭rs时出现了异常,那么程序将在关闭rs时非正常退出,这样就会导致pst、conn得不到关闭,从而导致资源泄漏。
为了保证关闭各资源时出现的异常不会相互影响,应该在关闭每个资源时分开使用try...catch块来保证关闭操作不会导致程序非正常退出。
importjava.sql.Connection;
importjava.sql.DriverManager;
importjava.sql.PreparedStatement;
importjava.sql.ResultSet;
importjava.sql.SQLException;
public class Tester {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "root";
Connection conn = null;
PreparedStatement pst = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url,user, password);
pst = conn.prepareStatement("select* from test");
rs = pst.executeQuery();
while(rs.next()) {
System.out.println(rs.getObject(0));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (pst != null) {
try {
pst.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
上面程序所示的资源关闭方式才是比较安全的,这种关闭方式主要保证如下3点:
1. 使用finally块来关闭物理资源,保证关闭操作总是会被执行;
2. 关闭每个资源之前首先保证引用该资源的引用变量不为null;
3. 为每个物理资源使用单独try...catch块关闭资源,保证关闭资源时引发的异常不会影响其他资源的关闭。
Java正常关闭资源的方式的更多相关文章
- Java异常关闭资源的两种方式
try-catch-finally 常用,在异常关闭时应判断流是否为空 public class CloseableUtils { public static void closeable(Close ...
- Effective java 系列之更优雅的关闭资源-try-with-resources
背景: 在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们.因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制,如果我们不在 ...
- Java进阶知识点:更优雅地关闭资源 - try-with-resource
一.背景 我们知道,在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们.因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制, ...
- Java进阶知识点3:更优雅地关闭资源 - try-with-resource及其异常抑制
一.背景 我们知道,在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们.因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制, ...
- java关闭资源,自制关闭资源工具类
在网上看到一篇关于关闭资源的正确方式:http://blog.csdn.net/bornforit/article/details/6896775 该博文中的总结: (1)使用finally块来关闭物 ...
- Java自学-I/O 关闭流的方式
关闭流的方式 所有的流,无论是输入流还是输出流,使用完毕之后,都应该关闭. 如果不关闭,会产生对资源占用的浪费. 当量比较大的时候,会影响到业务的正常开展. 步骤 1 : 在try中关闭 在try的作 ...
- 数据库连接工具类——包含取得连接和关闭资源 ConnUtil.java
package com.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Prepare ...
- java7增强的try语句关闭资源
java7增强的try语句关闭资源 传统的关闭资源方式 import java.io.FileInputStream; import java.io.FileOutputStream; import ...
- 更优雅地关闭资源 - try-with-resource及其异常抑制
原文:https://www.cnblogs.com/itZhy/p/7636615.html 一.背景 我们知道,在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在 ...
随机推荐
- (二)WebRTC手记之框架与接口
转自:http://www.cnblogs.com/fangkm/p/4370492.html 转载请注明出处:http://www.cnblogs.com/fangkm/p/4370492.html ...
- webpack入门--前端必备
webpack入门--前端必备 什么是 webpack? webpack是一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX).coffee.样式(含less/sass).图片等都作为模块来 ...
- 安装完最小化 RHEL/CentOS 7 后需要做的 30 件事情(三)码农网
12. 安装 Apache Tomcat Tomcat 是由 Apache 设计的用来运行 Java HTTP web 服务器的 servlet 容器.按照下面的方法安装 tomcat,但需要指出的是 ...
- ajax请求成功后打开新窗口地址
转自:http://www.cnblogs.com/linjiqin/p/3148205.html jQuery.ajax({ "type":"post&qu ...
- MySQL命令行查询乱码解决方法:
MySQL会出现中文乱码的原因不外乎下列几点:1.server本身设定问题,例如还停留在latin1 2.table的语系设定问题(包含character与collation) 3.客户端程式(例如p ...
- SU Demos-03T-F Analysis-02Sutvband
第一个脚本,生成震源扫描信号,并进行gabor变换 运行结果, 第二个脚本,利用时变滤波从和信号中重建单独的3个扫描信号 运行结果
- push和join
Push,向数组末尾添加元素,并返回长度. Join,将数组按照join参数连接起来. 不同浏览器对JS解析不同,Join比连接字符串快,要用大量数据测试,然后比时间.
- TFS2012团队管理基本配置及基础使用方法
本文介绍如何在VS2012中使用微软提供的TFS2012服务器进行团队协作开发,免费默认只支持5用户,主要分为两大步服务器配置跟客户端配置. 转载请标注:http://www.kwstu.com/Ar ...
- bzoj1016 [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3517 Solved: 1396[Submit][St ...
- iphone6来了,我该做点什么(兼容iphone6的方法)
北京时间2014年9月10日凌晨1点,苹果公司正式发布其新一代产品 iPhone6,相信做webapp开发的同学对它是充满了好奇和等待,也担心它带来各种坑爹,高清的分辨率,升级的retina显示屏,我 ...