还在用try-finally中关闭各种资源,你不累吗?

简介: 相信大多数人在使用Java的时候,经常会使用到try-finally去关闭各种打开的资源,比如数据库连接,文件流等。于是,我们的代码经常就会像这个样子:

相信大多数人在使用Java的时候,经常会使用到try-finally去关闭各种打开的资源,比如数据库连接,文件流等。于是,我们的代码经常就会像这个样子:


import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;public class ReadFile {    public static void main(String[] args) {       BufferedReader reader = null;        String buffer = null;        try {            reader = new BufferedReader(new FileReader("src/testRead.txt"));            do {                buffer = reader.readLine();                System.out.println(buffer);            } while (reader.read() != -1);        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                reader.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }}


一个简单的Java获取文件读取操作。可是代码却冗长的像老太婆的裹脚布又长又臭:我们在finally中为了防止关闭reader的时候发生异常,不得不再加一层的try-catch操作来进行异常捕获。


还有一个更大的问题是,假如在buffer = reader.readLine()这句语句抛出了异常,而同时,在finally中的reader.close()语句也发生了异常,那么finally块中的异常信息就会覆盖掉reader.readLine()语句的异常信息。也就是说异常堆栈跟踪中没有第一个异常的记录,这可能会使实际系统中的调试变得非常复杂。虽然可以通过编写代码来抑制第二个异常而支持第一个异常,但是这会使得编写的人员异常痛苦,而且代码也会越来越长。


那么怎么解决这样的问题呢?让人高兴的是,在Java7中引入了try-with-resources语句,就是用来处理这个问题的,我们看看用try-with-resources后的代码


import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;public class ReadFile {    public static void main(String[] args) {        String bufferSugar = null;        try (BufferedReader readerSugar = new BufferedReader(new FileReader("src/testRead.txt"))) {            bufferSugar = readerSugar.readLine();            System.out.println(bufferSugar);        } catch (IOException e) {            e.printStackTrace();        }    }}


是不是简单了很多,主要的代码都用来处理业务逻辑而没有去过多的关心资源的关闭。而且,如果异常是由 readLine 调用和不可见的 close 抛出的,则后一个异常将被抑制,以支持前一个异常。实际上,还可能会抑制多个异常,以保留实际希望看到的异常。这些被抑制的异常不会仅仅被抛弃;它们会被打印在堆栈跟踪中,并标记它们被抑制。可以通过编程方式使用 getSuppressed 方法访问到它们。


那么try-with-resources做了什么让我们不再需要自己手动调用资源的close呢?用jad工具反编译看看源码:


import java.io.*;public class ReadFile{    public ReadFile(){}    public static void main(String args[])    {        String bufferSugar = null;        Exception exception;        exception = null;        Object obj = null;        BufferedReader readerSugar = new BufferedReader(new FileReader("src/testRead.txt"));        bufferSugar = readerSugar.readLine();        System.out.println(bufferSugar);        if(readerSugar != null)            readerSugar.close();        break MISSING_BLOCK_LABEL_90;        exception;        if(readerSugar != null)            readerSugar.close();        throw exception;        Exception exception1;        exception1;        if(exception == null)            exception = exception1;        else        if(exception != exception1)            exception.addSuppressed(exception1);        throw exception;        IOException e;        e;        e.printStackTrace();    }}


可以看出try-with-resources为我们做了两件事:


  • 添加了close
  • try块里面和close函数都可能抛出异常,这里会将try块抛出的异常压缩成Suppressed Exceptions,可以调用Throwable.getSuppressed方法取出被抑制的异常


try-with-resources就是Java7为我们提供的一个语法糖啦。


所以,今后如果有在用到try-finally去处理资源的开启关闭的时候,记得有一种更加方便的方式:try-with-resources。


参考:

https://www.cnblogs.com/darrenqiao/p/9201357.html

相关文章
|
24天前
|
Java 测试技术
使用try-catch-finally关闭资源更优雅的关闭try-with-resource
使用try-catch-finally关闭资源更优雅的关闭try-with-resource
11 1
|
4月前
|
设计模式 消息中间件 前端开发
finally中的代码一定会执行吗?
finally中的代码一定会执行吗?
459 0
|
7月前
|
存储 C++
close()关闭文件方法
我们知道,调用 open() 方法打开文件,是文件流对象和文件之间建立关联的过程。那么,调用 close() 方法关闭已打开的文件,就可以理解为是切断文件流对象和文件之间的关联。注意,close() 方法的功能仅是切断文件流与文件之间的关联,该文件流并会被销毁,其后续还可用于关联其它的文件。 close() 方法的用法很简单,其语法格式如下: void close( ) 可以看到,该方法既不需要传递任何参数,也没有返回值。 举个例子: #include <fstream> using namespace std; int main() {
83 0
|
JSON 安全 前端开发
替代try catch处理异常的优雅方式
替代try catch处理异常的优雅方式
|
Java 数据库连接 数据库
try()catch{}自动释放资源
try()catch{}自动释放资源
182 0
|
Java 数据库连接 API
try-with-resource:自动地关闭资源
try-with-resource:自动地关闭资源
431 0
|
Java 测试技术 数据安全/隐私保护
你还在使用 try-catch-finally 关闭资源?
代码一定得写的优雅一点! 你还在使用try-catch-finally关闭资源吗,如果是,那么就有点out了。皮皮甜手把手教你使用JDK7引用的try-with-resource JDK7之前资源的关闭姿势:
126 0
如何实现不论是否发生异常都必须执行 使用关键字finally finally: 我们有一些场景 需要保证代码无论是否异常都要执行 需要放到finally里
如何实现不论是否发生异常都必须执行 使用关键字finally finally: 我们有一些场景 需要保证代码无论是否异常都要执行 需要放到finally里