Java 类 —— AutoCloseable

AutoCloseable 接口

概述

AutoCloseable 是从 jdk7 开始存在的接口,位于 java.lang 包中,用于自动执行资源关闭操作。AutoCloseable 接口定义了一个名为 close() 的方法,用于关闭资源。通常在实现 AutoCloseable 接口的类中重写 close() 方法来实现自定义关闭资源的逻辑,例如关闭文件、释放网络连接等。

AutoCloseable 接口是为了配合 Java 7 引入的 try-with-resources(try-catch-finally) 语句而设计的。使用 try-with-resources 语句可以自动关闭实现了 AutoCloseable 接口的资源,无需显式调用 close() 方法,确保资源在使用完毕后被正确关闭,提高代码的可靠性和安全性。

示例

1、在 try-catch-finally 中使用 AutoCloseable 来自动关闭资源:

自定义类实现 AutoCloseable 并重写 close() 方法:

public class StreamExample implements AutoCloseable {
    private BufferedReader reader;

    public StreamExample(String filePath) throws IOException {
        reader = new BufferedReader(new FileReader(filePath));
    }

    public String readLine() throws IOException {
        return reader.readLine();
    }

    /**
     * 重写 close() 方法,自定义关闭资源逻辑
     * @throws IOException
     */
    @Override
    public void close() throws IOException {
        reader.close();
    }
}

在 try-catch-finally 中的使用:

public class BaseTest {
    public static void main(String[] args) {
        // 在 try() 中使用自定义对象,在执行完 try 逻辑后会自动调用 close() 方法关闭资源。
        // 这样无需在 catch 或 finally 中编写关闭资源的逻辑了。
        try (StreamExample example = new StreamExample("file.txt")) {
            String line = example.readLine();
            while (line != null) {
                System.out.println(line);
                line = example.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2、不一定用来关闭资源,可以扩展为其它使用场景:

比如在 for 循环语句中,遍历每一个元素时,为每一个元素处理日志设置不同的 traceId,方便日志定位跟踪。

@Slf4j
public class TraceExample implements AutoCloseable {

    /**
     * 进入循环之前的traceId
     */
    private String beforeTraceId;

    public TraceExample(String beforeTraceId) {
        try {
            this.beforeTraceId = beforeTraceId;
            // 处理不同集合元素使用不同的 traceId,方便定位日志
            String newTraceId = UUID.randomUUID().toString().replaceAll("-", "");
            MDC.put("traceId", newTraceId);
        } catch (Exception e) {
            log.error("TraceExample init error", e);
        }
    }

    
    @Override
    public void close() {
        try {
            // 集合处理完后恢复遍历集合之前的 traceId
            MDC.put("traceId", this.beforeTraceId);
        } catch (Exception e) {
            log.error("TraceExample init error", e);
        }
    }
}

结合 try-catch-finally 在循环语句中使用:

public class BaseTest {
    public static void main(String[] args) {
        List<String> listData =  Arrays.asList("1","2", "3");
        for (int i = 0; i < listData.size(); i++) {
            // 在处理元素之前设置新的 traceId,元素处理完后再恢复原 traceId。
            try (TraceExample ignored = new TraceExample("beforeTraceId")) {
                System.out.println("处理元素:" + listData.get(i));
                System.out.println("每个元素处理过程中,新的traceId:" + MDC.get("traceId"));
            } catch (Exception e) {
                throw e;
            }
            System.out.println("原来的 traceId:" + MDC.get("traceId"));
        }
    }
}
  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值