try-with-resources
是 Java 7
中引入的一个新特性,用于简化资源管理
,一般是用于处理实现了 AutoCloseable 或 Closeable 接口的资源
(如文件、数据库连接
等),用于确保在使用完资源后自动关闭资源,避免资源泄漏
。
简化上面的内容其实就一个:自动关闭资源
。在了解自动关闭资源之前,我们看看,不自动关闭资源(也就是手动关闭)
是什么样的。
下面看看在传统try-catch-finally
语句中来手动关闭资源
的过程。
在我们常规的try-catch-finally
语句中经常可以看到这样的操作:
BufferedReader br = null;
try {
//在yry-catch中获取文件
br = new BufferedReader(new FileReader("example.txt"));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
//异常捕获
e.printStackTrace();
} finally {
if (br != null) {
try {
//注意这里 使用完资源需要关闭
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
亦或是以下的自己手动获取数据库连接
的操作:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TraditionalJDBCExample {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
// 加载JDBC驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 获取连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "admin", "123456");
String sql = "SELECT id, name, email FROM users";
stmt = conn.prepareStatement(sql);
// 执行查询
rs = stmt.executeQuery();
// 处理结果集 -伪代码
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
// 关闭相关资源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
请注意上面资源关闭的代码
无论是读取文件的:
br.close();
还是数据库的:
rs.close();
stmt.close();
conn.close();
都需要再加一层try-catch
,如果不加还不行
这样就导致我们的代码看起来非常的繁琐, try-catch
套了一层又一层,这可真是老母猪戴x罩: 一套又一套。
在上述的场景中,我们不仅要手动关闭资源,而且可能还要写额外代码,尤其是finally中的try-catch
,不写还不行。
但是如果我们使用try-cath-resources
的话其实就会简单很多
与上面的try-catch-finally
不一样,try-with-resources
的使用略有不同
try-catch-finally
的常规使用如下
try {
//声明自己的资源
} catch(Exception e) {
//抛出异常
} finally {
//关闭资源
}
try-with-resources
的使用如下,注意try后面的括号
,相较于上面多了一个()
,括号内是需要关闭的资源
try(
//需要自动关闭的资源 执行结束会自动关闭
) {
//对资源的操作
} catch(Exception e) {
//抛出异常
}
//由于不需要手动关闭资源,所以不需要finally
来将上面的读取文件部分代码,改为try-with-resources
如下
//把资源放入try的()中 里面的资源会自动关闭
try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
明显简洁了很多
同样的,相对于获取数据库连接也使用try-with-resources
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TryWithResourcesJDBCExample {
public static void main(String[] args) {
// 加载JDBC驱动
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
return;
}、
String url = "jdbc:mysql://localhost:3306/mydatabase";
String username = "admin";
String password = "123456";
String sql = "SELECT id, name, email FROM users";
使用try-with-resources语句来管理资源
try (
//这里面的资源会自动关闭
Connection conn = DriverManager.getConnection(url, username, password);
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery()
) {
// 处理结果集 -- 伪代码
} catch (SQLException e) {
e.printStackTrace();
}
}
}
省略了finally中的关闭资源的代码
后,明显简洁了很多。
那么什么时候用呢?
还记得我们开头的那句话吗:实现了 AutoCloseable 或 Closeable 接口的资源
你只需要按住ctrl
点你使用的资源类,查看它以及它的父类有没有实现AutoCloseable或者Closeable接口
,只要有以下的内容,大胆的用
或者是文件的读取
你像常规的InputStream、OutputStream以及其子类
都是可以用的
还有一些比如Ftp相关
以及网络编程的Socket
也可以用
还是那句话,能不能用,点进去看看就知道了
下课下课