下面这两段代码我想写过Java的人都很清楚,也许自己就经常这么写。
//复制文件
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("D:\\readme.txt");
fos = new FileOutputStream("D:\\test.txt");
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null)
fos.close();
if (fis != null)
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//连接数据库并查询数据
Connection connection = null;
ResultSet resultSet = null;
try {
connection = DBHelper.getConnection();
Statement statement = connection.createStatement();
resultSet = statement.executeQuery("select * from table1");
while (resultSet.next()) {
System.out.println(resultSet.getString(1));
System.out.println(resultSet.getString(2));
System.out.println(resultSet.getString(3));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
try {
if (resultSet != null)
resultSet.close();
if (connection != null)
connection.close();
;
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
尽管我们对这种模块化的代码深恶痛绝,明明有用的代码就那么行句,为了执行这几行代码我们又不得不写多几倍的代码,人在讲话身不由己啊。
好在Java社区的开发者也遇到了这种痛,在jdk1.7之后终于给出了一个好的解决方案,那就是try-with-resource的写法,上面两段代码在使用try-with-resource后可以写成这个样子
try(FileInputStream fis = new FileInputStream("D:\\readme.txt");
FileOutputStream fos = new FileOutputStream("D:\\test.txt");) {
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try(Connection connection = DBHelper.getConnection();
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("select * from table1");) {
while (resultSet.next()) {
System.out.println(resultSet.getString(1));
System.out.println(resultSet.getString(2));
System.out.println(resultSet.getString(3));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
咋一看,确实代码优雅了不少,再也不用在finally里面再去try catch了,今天我们就聊聊这个try-with-resource,从字面上来看try-with-resource意思是尝试使用资源,那它的执行流程是什么样的呢?在什么情况下能使用这种方式呢?
首先什么是资源呢?但从中文理解这个范围就太大了,一个文件、一个数据库连接是不是资源?当时Java里面不是这么理解,在try-with-resource里面,必须要实现了AutoCloseable结构才能算是资源,那为什么一定要实现AutoCloseable接口呢?因为在try后面括号定义的对象,在try里面的代码执行完成或者抛出异常后,会去调用close方法,而这个close方法就是AutoCloseable定义的方法,所以只有实现了AutoCloseable接口的类才能放在try-with-resource里面。后面在开发的过程中可以尝试使用这种方式去关闭资源哦,相信我,用了一次你就会爱上他的。