前言
本文章帮助大家对AutoCloseable
接口的理解。
一、概述
AutoCloseable
意为可自动关闭的。顾名思义,为在try-with-resources语句中使用的“资源”对象(如文件、套接字句柄等)可在块结束后自动关闭,需要实现此接口。
重点:try-with-resources语句如:try(/*在此使用可自动关闭的资源对象,多个对象用分号隔开...*/) { /*...*/ } catch ...
,其中的“资源对象”需要实现此接口。
二、源码理解
包
package java.lang;
使用AutoCloseable
接口时,此包自动引入。
AutoCloseable接口
public interface AutoCloseable { /*...*/ }
注意:只有实现此接口才能在try-with-resources语句中起自动关闭的效果。若语句中使用的是实现了其它具有close
方法的接口,编译时将报“不兼容的类型”的异常,异常信息如下(中文版本):
java: 不兼容的类型: try-with-resources 不适用于变量类型
(MyResource无法转换为java.lang.AutoCloseable)
使用例子如下,程序最终将打印三个“0”,即三个资源都会自动调用其close
方法:
class MyResource implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println(0);
/*关闭资源*/
}
}
MyResource resource1 = new MyResource();
try (resource1; MyResource resource2 = new MyResource(); MyResource resource3 = new MyResource()) {
/*...*/
}
catch (Exception e) {
/*...*/
}
编译源码参考:
- Attr.java的
public void visitTry(JCTry tree)
(访问“try”语句)的boolean isTryWithResource = tree.resources.nonEmpty()
(带资源的“try”(简称“twr”))、CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext)
(twr上下文)的chk.basicHandler.report(pos, diags.fragment(Fragments.TryNotApplicableToType(details)))
(twr上下文的重写报告方法,调用basicHandler
的报告方法。带“不适用的变量类型”信息)、twrResult.check(resource, resource.type);
(检查)、return chk.checkType(pos, found, pt, checkContext)
; - Check.java的
if (checkContext.compatible(found, req, checkContext.checkWarner(pos, found, req)))
(类型可比较)、checkContext.report(pos, diags.fragment(Fragments.InconvertibleTypes(found, req)))
(不可比较时,调用twr上下文的报告方法。带“无法转换为”信息)、CheckContext basicHandler = new CheckContext()
的public void report(DiagnosticPosition pos, JCDiagnostic details)
(basicHandler
的报告方法)的log.error(pos, Errors.ProbFoundReq(details))
(打印“不兼容的类型”和其它错误信息); - Symtab.java的
autoCloseableType = enterClass("java.lang.AutoCloseable")
; - CompilerProperties.java的
public static Fragment ProbFoundReq(JCDiagnostic arg0)
的return new Fragment("compiler", "prob.found.req", arg0)
(不兼容的类型)、public static Fragment TryNotApplicableToType(JCDiagnostic arg0)
的return new Fragment("compiler", "try.not.applicable.to.type", arg0);
(不适用于变量类型)、public static Fragment InconvertibleTypes(Type arg0, Type arg1)
的return new Fragment("compiler", "inconvertible.types", arg0, arg1);
(无法转换为)。
AutoCloseable方法
close
void close() throws Exception;
重点:关闭此对象所持资源,若资源不能被关闭,抛出Exception
异常。重写此方法以自定义关闭资源方法。此方法在try-with-resources语句头中的对象上块结束后自动调用。
注意:close
方法抛出的异常也能被catch
语句捕获到,并且其异常会被抑制。实现类不能抛InterruptedException
异常,因为中断异常被抑制的话可能导致运行时不当行为。建议实现方法时考虑调用此方法具有幂等性,即多次调用没有其他副作用。
总结
新人源码理解,望大家多多指点。