“要养成输入流、输出流用完后关闭的习惯。”
之前学习Java时牢牢记住了视频里老师的这句话,然后之后用Java操作输入、输出流的时候都这样:
try{
}catch(){
}finally{
//在这里手动调用close()关闭流
}
包括网络上的很多文章也是这样写,这让我一直以为是这样的。
直到今天在仔细研究IO类源代码的时候发现字节流的InputStream
、OutputStream
和字符流的Writer
、Reader
都实现了Closeable
接口,而Closeable
接口继承了AutoCloseable
接口(Java SE 7(1.7)新增),网上查阅得知实现AutoCloseable
接口后,便可通过try-catch-resources语句创建资源,并且会在try{}执行完之后自动调用close()
方法释放资源,而无需手动调用,。例如,自己创建一个T类实现Closeable
接口,实现close()
方法:
再使用如下的try-catch结构创建T的对象:
输出结果显示,在并未调用close()
方法的情况下,执行完try{}后,自动调用了close()
方法。而不再需要在finally{}中手动调用close()
。
哎,想起来也是啊,我是2016年初看的Java‘教学视频,我再去翻视频看老师用的Java版本,结果是2006年发布的Java SE 6(1.6),视频录制时间是2011年2月,而2011年7月发布的Java SE 7支持了这种写法……
害得我close()
了这么久。看来以后看教学视频要尽量选新的了,不过奇怪网上那么多文章都是手动close()
。
try-catch-resources语句是我在网上搜索到的,之前没有听过这种写法,于是我打开Java官方的Java Language Specification文档看看最权威的语法规范:点此查看,
A try-with-resources statement is parameterized with variables (known as resources) that are initialized before execution of the try block and closed automatically, in the reverse order from which they were initialized, after execution of the try block. catch clauses and a finally clause are often unnecessary when resources are closed automatically.
try-with-resources 语句使用变量(称为资源)参数化,这些变量在执行 try 块之前被初始化,并在执行 try 块之后按照它们被初始化的相反顺序自动关闭。 当资源自动关闭时,通常不需要 catch 子句和 finally 子句。
The resource specification denotes the resources of the try-with-resources statement, either by declaring local variables with initializer expressions or by referring to existing variables.
资源规范表示 try-with-resources 的资源声明,或者通过使用初始化表达式声明局部变量或通过引用现有变量。
按照文档的说法编写如下程序:
运行后输出,正如文档中所说,按照try()里变量反向从右到左调用了close()
方法。
而不是按照变量初始化的顺序,修改一下代码:
运行结果说明不是按照变量初始化的顺序反向调用close()
翻译里说“按照它们被初始化的相反顺序自动关闭”,所以有时候使用翻译会造成歧义,特别是像这种严谨的官方文档,就需要一个词一个词的理解。
文档下文就规定了try()里的变量必须是AutoCloseable
的子类型,即间接实现了此接口。这就与上文讲的一样了。
The type of a local variable declared in a resource specification, or the type of an existing variable referred to in a resource specification, must be a subtype of AutoCloseable, or a compile-time error occurs.
资源规范中声明的局部变量的类型,或资源规范中引用的现有变量的类型,必须是 AutoCloseable 的子类型,否则会发生编译时错误。
哎,更多细节以后再慢慢研究吧,全英文的专业文档看起来真头大,只恨英语水平不够,要好好学英语了。