六、优雅关闭资源

资源关闭优化前与优化后的对比

/**
 * @author fangliu
 * @date 2020-02-15
 * @description 资源关闭优化前与优化后的对比
 */
public class ResourceCloseVs {


    @Test
    public void oldFileHandle(String url, FileConsumer fileConsumer){
        // 声明
        FileInputStream fileInputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        // 创建文件读取流
        try {
            fileInputStream = new FileInputStream(url);
            inputStreamReader = new InputStreamReader(fileInputStream);
            bufferedReader = new BufferedReader(inputStreamReader);
            // 定义行变量和内容sb
            String line;
            StringBuilder stringBuilder = new StringBuilder();
            // 循环读取文件类容
            while((line = bufferedReader.readLine()) != null){
                stringBuilder.append(line + "\n");
            }
            // 调用函数式接口方法,将文件内容传递给lambda表达式,实现业务逻辑
            fileConsumer.fileHandler(stringBuilder.toString());
        }catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 关闭流资源
            if (bufferedReader != null){
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStreamReader != null){
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fileInputStream != null){
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Test
    public void newFileHandle(String url, FileConsumer fileConsumer){
        // 声明创建文件读取流
        try {
            FileInputStream fileInputStream = new FileInputStream(url);
            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            // 定义行变量和内容sb
            String line;
            StringBuilder stringBuilder = new StringBuilder();
            // 循环读取文件类容
            while((line = bufferedReader.readLine()) != null){
                stringBuilder.append(line + "\n");
            }
            // 调用函数式接口方法,将文件内容传递给lambda表达式,实现业务逻辑
            fileConsumer.fileHandler(stringBuilder.toString());
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

垃圾回收的特点

  • 垃圾回收机制只负责回收堆内存资源,不会回收任何物理资源
  • 程序无法精确控制垃圾回收动作的具体发生时间
  • 在垃圾回收之前,总会先调用它的finalize方法

常见手动释放的物理资源

  • 文件/流资源
  • 套接字资源
  • 数据库连接资源

TWR简介

  • java7引入的新特性
  • 优雅的关闭资源
  • 一种java语法糖

使用try-with-resource关闭资源

  • 多资源自动关闭
  • 实现AutoCloseable接口
  • 避免异常屏蔽

实例

/**
 * @author fangliu
 * @date 2020-02-15
 * @description 基于JDK 1.7之后,实现正确关闭流资源方法
 * try - with - resource
 */
public class NewFileCopyTest {

    @Test
    public void copyFile(){
        // 定义输入输出路径
        String originalUrl ="lib/NewFileCopyTest.java";
        String targetUrl = "targetTest/new.txt";

        // 初始化输入输出流对象
        try (
                FileInputStream fileInputStream = new FileInputStream(originalUrl);
                FileOutputStream fileOutputStream = new FileOutputStream(targetUrl);
             ){
                   int content;
                   // 迭代拷贝数据
                   while((content = fileInputStream.read()) != -1){
                       fileOutputStream.write(content);
                   }
        }catch (FileNotFoundException e){
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

反编译源码分析

只是jdk提供的一种java语法糖,当编译成可运行的class文件会
跟处理成手动关闭流一样。

资源关闭特殊情况

  • 资源对象被return的情况下,由调用方关闭
  • ByteArrayInputStream等不需要检查关闭的资源对象
  • 使用Socket获取的InputStream和OutputStream对象不需要关闭
posted @ 2020-11-18 20:54  柳小白  阅读(133)  评论(0编辑  收藏  举报