为什么要手动关闭资源呢
开篇先说下 为什么要手动关闭资源呢
Java不是说有垃圾回收机制吗,为什么还需要手动关闭资源呢
解释:
因为GC只管内存不管别的资源。假如有内存以外的其它资源依附在Java对
上,如native
memory(DirectByteBuffer)、file(FileInputStream)之类,那当然自己
关闭最合适。为了“避免”程序员忘了自己释放那些资源,Java提供了finaliz
er、PhantomReference之类的机制来让程序员向GC注册“自动回调释放资源”
的功能。但GC回调它们的时机不确定,所以只应该作为最后手段来使用,主
要手段还是自己关闭最好
常见需要手动释放得物理资源
1、文件/流资源
2、套接字资源
3、数据库连接资源
物理资源可以不手动释放吗
1、资源长时间无效占用
2、超过最大限制后,将无资源可用
3、导致系统无法正常运行
步入正题,try-with-resource 与传统关闭 对比使用
package gom.gc.guoshicheng.lambda.resource;
import org.junit.Test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* jdk7 之前得文件拷贝功能
*/
public class FileCopyTest {
@Test
public void copyFile() {
/**
* 1、创建输入/输入流
* 2、执行文件拷贝,读取文件内容,写入到另一个文件中
* 3、 **关闭文件流资源**
*/
//定义输入路径和输出路径
String originalUrl = "D:\\work\\source\\学习\\_996\\src\\test\\java\\gom\\gc\\guoshicheng\\lambda\\resource\\FileCopyTest.java";
String targetUrl = "D:\\work\\source\\学习\\_996\\target\\FileCopyTeste.java";
//声明文件输入流,文件输入流
FileInputStream originalFileInputStream = null;
FileOutputStream targetFileOutputStream = null;
try {
//实例化文件流对象
originalFileInputStream =
new FileInputStream(originalUrl);
targetFileOutputStream =
new FileOutputStream(targetUrl);
//读取得字节信息
int content;
//迭代,读取/写入字节
while ((content = originalFileInputStream.read()) != -1) {
targetFileOutputStream.write(content);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭流资源
if (targetFileOutputStream != null) {
try {
targetFileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (originalFileInputStream != null) {
try {
originalFileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
class NewFileCopyTest {
@Test
public void copyFile() {
//先定义输入/输出路径
String originalUrl = "D:\\work\\source\\学习\\_996\\src\\test\\java\\gom\\gc\\guoshicheng\\lambda\\resource\\FileCopyTest.java";
String targetUrl = "D:\\work\\source\\学习\\_996\\target\\FileCopyTeste.java";
try (
//声明文件输入流,文件输入流
FileInputStream originalFileInputStream = new FileInputStream(originalUrl);
FileOutputStream targetFileOutputStream = new FileOutputStream(targetUrl);
) {
//读取得字节信息
int content;
//迭代,读取/写入字节
while ((content = originalFileInputStream.read()) != -1) {
targetFileOutputStream.write(content);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
资源关闭特殊情况
1、资源对象被return的情况下,由调用方关闭
2、ByteArrayInputStream等不需要检查关闭的资源对象
3、使用Socket获取的InputStream和OutputStream对象不需要关闭,因为socket关闭的时候自然就关闭了
总结
最重要的一点,就是try-with-resource的使用,代码量减少了