- By刘立博
- 2021-06-14 22:04:38
- 681人已阅读
常见需手动释放的物理资源
文件、流资源
套接字资源
数据库连接资源
不释放物理资源的后果
对资源无效占用
超过操作系统最大限制后,无法打开新的物理资源
导致系统无法正常运行
一个栗子
传统方法实现文件拷贝
实例化输入流和输出流,完成相关业务操作后,在finally块中完成物理资源的释放
public void copyFile()
{
String sourceUrl = "";
String targetUrl = "";
FileInputStream sourceFileInputStream = null;
FileOutputStream targetFileOutputStream = null;
try{
sourceFileInputStream = new FileInputStream(sourceUrl);
targetFileOutputStream = new FileOutputStream(targetUrl);
int read;
while ( (read = sourceFileInputStream.read()) != -1)
{
targetFileOutputStream.write(read);
}
}catch (Exception e){
e.printStackTrace();
} finally {
if(sourceFileInputStream != null)
{
try {
sourceFileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(targetFileOutputStream != null)
{
try {
targetFileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
使用TWR方式
在try代码块中进行输入流和输出流的实例化操作,JDK会自动释放物理资源
public void copyFileNew()
{
String sourceUrl = "";
String targetUrl = "";
try(
FileInputStream sourceFileInputStream = new FileInputStream(sourceUrl);
FileOutputStream targetFileOutputStream = new FileOutputStream(targetUrl)
)
{
int read;
while ( (read = sourceFileInputStream.read()) != -1)
{
targetFileOutputStream.write(read);
}
}catch (Exception e){
e.printStackTrace();
}
}
原理
JDK是如何实现物理资源释放的呢?使用反编译工具查看编译后的代码可知:所谓的TWR类似C语言的宏,编译器在编译时,会基于try括号中的物理资源声明,自动生成finally代码块,完成资源释放
public void copyFileNew() {
String sourceUrl = "";
String targetUrl = "";
try {
FileInputStream sourceFileInputStream = new FileInputStream(sourceUrl);
try {
FileOutputStream targetFileOutputStream = new FileOutputStream(targetUrl);
int read;
try {
while((read = sourceFileInputStream.read()) != -1) {
targetFileOutputStream.write(read);
}
} catch (Throwable var9) {
try {
targetFileOutputStream.close();
} catch (Throwable var8) {
var9.addSuppressed(var8);
}
throw var9;
}
targetFileOutputStream.close();
} catch (Throwable var10) {
try {
sourceFileInputStream.close();
} catch (Throwable var7) {
var10.addSuppressed(var7);
}
throw var10;
}
sourceFileInputStream.close();
} catch (Exception var11) {
var11.printStackTrace();
}
}