Should .close() be put in finally block or not?
The following are 3 different ways to close a output writer. The first one puts close() method in try clause, the second one puts close in finally clause, and the third one uses a try-with-resources statement. Which one is the right or the best?
//close() is in try clause
try {
PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter("out.txt", true)));
out.println("the text");
out.close();
} catch (IOException e) {
e.printStackTrace();
}
//close() is in finally clause
PrintWriter out = null;
try {
out = new PrintWriter(
new BufferedWriter(
new FileWriter("out.txt", true)));
out.println("the text");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
//try-with-resource statement
try (PrintWriter out2 = new PrintWriter(
new BufferedWriter(
new FileWriter("out.txt", true)))) {
out2.println("the text");
} catch (IOException e) {
e.printStackTrace();
}
Answer
Because the Writer should be closed in either case (exception or no exception), close() should be put in finally clause.
From Java 7, we can use try-with-resources statement.Why?
The try-with-resources Statement
The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
The following example reads the first line from a file. It uses an instance of BufferedReader to read data from the file. BufferedReader is a resource that must be closed after the program is finished with it:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
In this example, the resource declared in the try-with-resources statement is a BufferedReader. The declaration statement appears within parentheses immediately after the try keyword. The classBufferedReader, in Java SE 7 and later, implements the interface java.lang.AutoCloseable. Because theBufferedReader instance is declared in a try-with-resource statement, it will be closed regardless of whether the try statement completes normally or abruptly (as a result of the method BufferedReader.readLinethrowing an IOException).
Prior to Java SE 7, you can use a finally block to ensure that a resource is closed regardless of whether thetry statement completes normally or abruptly. The following example uses a finally block instead of a try-with-resources statement:
static String readFirstLineFromFileWithFinallyBlock(String path)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
However, in this example, if the methods readLine and close both throw exceptions, then the methodreadFirstLineFromFileWithFinallyBlock throws the exception thrown from the finally block; the exception thrown from the try block is suppressed. In contrast, in the example readFirstLineFromFile, if exceptions are thrown from both the try block and the try-with-resources statement, then the methodreadFirstLineFromFile throws the exception thrown from the try block; the exception thrown from thetry-with-resources block is suppressed. In Java SE 7 and later, you can retrieve suppressed exceptions; see the section Suppressed Exceptions for more information.
You may declare one or more resources in a try-with-resources statement. The following example retrieves the names of the files packaged in the zip file zipFileName and creates a text file that contains the names of these files:
public static void writeToFileZipFileContents(String zipFileName,
String outputFileName)
throws java.io.IOException { java.nio.charset.Charset charset =
java.nio.charset.StandardCharsets.US_ASCII;
java.nio.file.Path outputFilePath =
java.nio.file.Paths.get(outputFileName); // Open zip file and create output file with
// try-with-resources statement try (
java.util.zip.ZipFile zf =
new java.util.zip.ZipFile(zipFileName);
java.io.BufferedWriter writer =
java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
) {
// Enumerate each entry
for (java.util.Enumeration entries =
zf.entries(); entries.hasMoreElements();) {
// Get the entry name and write it to the output file
String newLine = System.getProperty("line.separator");
String zipEntryName =
((java.util.zip.ZipEntry)entries.nextElement()).getName() +
newLine;
writer.write(zipEntryName, 0, zipEntryName.length());
}
}
}
In this example, the try-with-resources statement contains two declarations that are separated by a semicolon:ZipFile and BufferedWriter. When the block of code that directly follows it terminates, either normally or because of an exception, the close methods of the BufferedWriter and ZipFile objects are automatically called in this order. Note that the close methods of resources are called in the opposite order of their creation.
The following example uses a try-with-resources statement to automatically close a java.sql.Statementobject:
public static void viewTable(Connection con) throws SQLException {
String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES";
try (Statement stmt = con.createStatement()) {
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
String coffeeName = rs.getString("COF_NAME");
int supplierID = rs.getInt("SUP_ID");
float price = rs.getFloat("PRICE");
int sales = rs.getInt("SALES");
int total = rs.getInt("TOTAL");
System.out.println(coffeeName + ", " + supplierID + ", " +
price + ", " + sales + ", " + total);
}
} catch (SQLException e) {
JDBCTutorialUtilities.printSQLException(e);
}
}
The resource java.sql.Statement used in this example is part of the JDBC 4.1 and later API.
Note: A try-with-resources statement can have catch and finally blocks just like an ordinary try statement. In a try-with-resources statement, any catch or finally block is run after the resources declared have been closed.
Suppressed Exceptions
An exception can be thrown from the block of code associated with the try-with-resources statement. In the example writeToFileZipFileContents, an exception can be thrown from the try block, and up to two exceptions can be thrown from the try-with-resources statement when it tries to close the ZipFile andBufferedWriter objects. If an exception is thrown from the try block and one or more exceptions are thrown from the try-with-resources statement, then those exceptions thrown from the try-with-resources statement are suppressed, and the exception thrown by the block is the one that is thrown by thewriteToFileZipFileContents method. You can retrieve these suppressed exceptions by calling theThrowable.getSuppressed method from the exception thrown by the try block.
Classes That Implement the AutoCloseable or Closeable Interface
See the Javadoc of the AutoCloseable and Closeable interfaces for a list of classes that implement either of these interfaces. The Closeable interface extends the AutoCloseable interface. The close method of theCloseable interface throws exceptions of type IOException while the close method of the AutoCloseableinterface throws exceptions of type Exception. Consequently, subclasses of the AutoCloseable interface can override this behavior of the close method to throw specialized exceptions, such as IOException, or no exception at all.
Should .close() be put in finally block or not?的更多相关文章
- Objective-C中block的底层原理
先出2个考题: 1. 上面打印的是几,captureNum2 出去作用域后是否被销毁?为什么? 同样类型的题目: 问:打印的数字为多少? 有人会回答:mutArray是captureObject方法的 ...
- iOS 键盘添加完成按钮,delegate和block回调
这个是一个比较初级一点的文章,新人可以看看.当然实现这个需求的时候自己也有一点收获,记下来吧. 前两天产品要求在工程的所有数字键盘弹出时,上面带一个小帽子,上面安装一个“完成”按钮,这个完成按钮也没有 ...
- python中IndentationError: expected an indented block错误的解决方法
IndentationError: expected an indented block 翻译为IndentationError:预期的缩进块 解决方法:有冒号的下一行要缩进,该缩进就缩进
- JDBC Tutorials: Commit or Rollback transaction in finally block
http://skeletoncoder.blogspot.com/2006/10/jdbc-tutorials-commit-or-rollback.html JDBC Tutorials: Com ...
- 嵌入式&iOS:回调函数(C)与block(OC)传 参/函数 对比
C的回调函数: callBack.h 1).声明一个doSomeThingCount函数,参数为一个(无返回值,1个int参数的)函数. void DSTCount(void(*CallBack)(i ...
- 嵌入式&iOS:回调函数(C)与block(OC)回调对比
学了OC的block,再写C的回调函数有点别扭,对比下区别,回忆记录下. C的回调函数: callBack.h 1).定义一个回调函数的参数数量.类型. typedef void (*CallBack ...
- Block解析(iOS)
1. 操作系统中的栈和堆 我们先来看看一个由C/C++/OBJC编译的程序占用内存分布的结构: 栈区(stack):由系统自动分配,一般存放函数参数值.局部变量的值等.由编译器自动创建与释放.其操作方 ...
- CSS学习笔记——包含块 containing block
以下内容翻译自CSS 2.1官方文档.网址:https://www.w3.org/TR/CSS2/visudet.html#strut 有时,一个元素的盒子的位置和尺寸根据一个确定的矩形计算,这个确定 ...
- 用block做事件回调来简化代码,提高开发效率
我们在自定义view的时候,通常要考虑view的封装复用,所以如何把view的事件回调给Controller就是个需要好好考虑的问题, 一般来说,可选的方式主要有target-action和de ...
- 关于多个block问题
在某个添加文本的页面中,leftbarbutton是删除(直接将数组中的这个string删除),rightbarbutton是完成,分别对应两个block,完成的block是一开始写的,写到了view ...
随机推荐
- qt+2012+qtcreator 配置
这个配置搞了我好久,终于搞定了,网上一大堆,总是看不懂,后来自己摸索出来的. 先贴图: 如上图:有两种配置方案: 第一:用vs2012做开发编辑.只要下载和对应插件即可,安装路径不要有空格.安装好之后 ...
- 使用C#调用windows API入门
一:入门,直接从 C# 调用 DLL 导出 其实我们的议题应该叫做C#如何直接调用非托管代码,通常有2种方法: 1. 直接调用从 DLL 导出的函数. 2. 调用 COM 对象上的接口方法 我 ...
- TCP/IP详解学习笔记(2)-- 数据链路层
1.概述 数据链路层属于计算机网络的底层,使用的信道主要有点对点信道和广播信道两种类型. 在TCP/IP协议族中,数据链路层主要有三个目的: 1)为IP模块发送 ...
- gcov源码,供学习使用。
摘自http://www.opensource.apple.com/source/gcc/gcc-5484/gcc/gcov.c /* Gcov.c: prepend line execution c ...
- redis使用
1.服务器 下载redis Windows版,命令行启动redis-server.exe即可. 2.客户端使用 jedis 添加DLL: commons-pool2-2.0.jar jedis-2.4 ...
- 021ARM处理器工作模式
1.User模式:usr,普通应用程序运行的模式: 2.FIQ模式:fiq,快速中断模式,当一个程序正在运行时,突然产生一个中断,而且这种中断属于快速中断,那么将进入快速中断模式下运行: 3.IRQ模 ...
- maven项目使用mybatis-generator自动生成代码
1.添加mybatis-generator插件,打开pom.xml文件 在project节点下添加: <build> <plugins> <!-- MyBatis代码生成 ...
- Hive[1] 初识 及 安装
本文前提是Hadoop & Java & mysql 数据库,已经安装配置好,并且 环境变量均已经配置到位 声明:本笔记参照 学习<Hive 编程指南>而来,如果有错误 ...
- linux ubuntu装机到可实现java(eclipse,intellij IDEA,android)开发全过程
前言:linux是个很强的东西,你可以在其中体验开发的神速,有如神助,但是同时系统的不完整,错误漏洞多也是ubuntu等系统的诟病,所以大家遇到任何问题,第一时间请淡定,随后百度,google一下吧, ...
- Linux Hugetlbfs内核源码简析-----(二)Hugetlbfs挂载
本文只讨论执行"mount none /mnt/huge -t hugetlbfs"命令后,mount系统调用的执行过程(基于Linux-3.4.51),不涉及进程相关的细节. m ...