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 ...
随机推荐
- [AFUI]App Framework
---------------------------------------------------------------------------------------------------- ...
- centos7安装tftp服务器
1.安装 su #进入root yum install xinetd yum install tftp yum install tftp-server 2.配置tftp vim /etc/xinetd ...
- No.001 Two Sum
Two Sum Total Accepted: 262258 Total Submissions: 1048169 Difficulty: Easy Given an array of integer ...
- linx 实用操作命令二
pcre相关操作pcretest -C #查看pcre是否支持utf8 rpm -q -a #查看软件包列表rpm -ql pcre-7.8-6.el6.x86_64 #查看包安装的位置rpm -e ...
- PL/SQL 导入excel表格到oracle数据表
通过使用PL/SQL 批量查询取数时,将excel中的每一列数据复制黏贴进新建的中间表,黏贴时会有贴歪的情况,也就是某些列会从第二第三行开始插入整列,导致数据乱掉,然后好像又不支持批量删除整列数据,所 ...
- [drp 4] 使用dom4j,读取XML数据,保存至数据库
导读:上篇文章介绍了用XML文件配置数据库的连接,然后通过读取XML文件连接数据库的内容,本篇博客介绍读取XML文件,进行数据持久化的操作.PS:从某种意义上来说,经过Scheme校正的XML文件,本 ...
- js中object的申明方法
//js中的对象申明使用new Object(); //object类型的数据类似于数组通过下表来访问其中的值 //example1 var person=new Object(); person.n ...
- java 进制相互转换
public class test{ public static void main(String[]args){ //十进制转二进制. public static void toBin(int nu ...
- RAW格式
一.什么是RAW文件?RAW文件主要是一种记录了数码相机传感器的原始信息,同时伴随着一些由相机所产生的一些元数据(metadata,诸如IS0的设置.快门速度.光圈值.白平衡等)的文件.不同的相机制造 ...
- linux 内核(驱动)常用函数
2.4.1 内存申请和释放 include/linux/kernel.h里声明了kmalloc()和kfree().用于在内核模式下申请和释放内存. void *kmalloc(unsigned ...