使用try-with-resources替代try finally释放资源

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

1、旧社会

Java里,对于文件操作IO流、数据库连接等开销非常昂贵的资源,用完之后必须及时通过close方法将其关闭,否则资源会一直处于打开状态,直至程序停止,增加系统负担。

关闭资源的常用方式就是在finally块里是释放,即调用close方法。比如,我们经常会写这样的代码:

public static void main(String[] args) {BufferedReader br = null;try {String line;br = new BufferedReader(new FileReader("d:\\testing.txt"));while ((line = br.readLine()) != null) {System.out.println(line);}} catch (IOException e) {// handle exception} finally {try {if (br != null) {br.close();}} catch (IOException ex) {// handle exception}}
}

可以看出,为了关闭资源以及处理关闭资源时可能出现的异常,不得不写一大推代码。

2、新时代

2.1 使用新写法

从Java 7开始,jdk提供了一种更好的方式关闭资源,使用try-with-resources语句,改写一下上面的代码,效果如下:

public static void main(String[] args) {try(BufferedReader br = new BufferedReader(new FileReader("d:\\testing.txt"))) {String line;while ((line = br.readLine()) != null) {System.out.println(line);}} catch (IOException e) {// handle exception}
}

清爽了很多是不是? 但是,有没有一点不安呢?

2.2 新问题

原来释放资源的时候如果发生异常,我们可以在finally块中catch新异常,然后继续处理。但是新方式没有了finally块,异常是如何抛出的?如果关闭资源时发生异常怎么办?我们怎么处理?

从文档上可以找到这样一段描述:

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. You can retrieve these suppressed exceptions by calling the Throwable.getSuppressed method from the exception thrown by the try block.

意思是:如果 try 块抛出异常并且 try-with-resources 语句抛出一个或多个异常,那么从 try-with-resources 语句中抛出的异常将会被忽略。你可以通过调用由 try块抛出的异常的Throwable.getSuppressed 方法检索这些被忽略的异常信息。

在明确一点说就是:

  • 如果try块异常,catch到的是try块抛出的异常;
  • 如果try块正常,close异常,catch到的是close抛出的异常;
  • 如果try块异常,close也异常,catch到的是try块抛出的异常,close异常被忽略。

基于这几种情况,我们做几个测试分别验证一下:

2.2.1 try块异常

大家都懂,略。

2.2.2 try块正常,close异常

public class TestTryWithResources {public static void main(String[] args) {try (MyResource resource = new MyResource()) {} catch (Exception e) {System.out.println("捕获异常: " + e.getMessage());}}
}/*** 自定义一个资源类,close时抛出异常** ps:只有实现AutoCloseable或Closeable接口的对象才能用try-with-resources*/
class MyResource implements AutoCloseable {@Overridepublic void close() throws Exception {System.out.println("执行close方法,释放资源");throw new Exception("释放资源异常");}
}

执行结果为: 执行close方法,释放资源 捕获异常: 释放资源异常

即,catch到的是close方法抛出的异常

2.2.3 try块异常,close也异常

public class TestTryWithResources {public static void main(String[] args) {try (MyResource resource = new MyResource()) {throw new Exception("try块异常");} catch (Exception e) {System.out.println("捕获异常: " + e.getMessage());// 找到被忽略的异常Throwable[] ts = e.getSuppressed();for(Throwable t : ts) {System.out.println("被忽略的异常"+ t.getMessage());}}}
}/*** 自定义一个资源类,close时抛出异常*/
class MyResource implements AutoCloseable {@Overridepublic void close() throws Exception {System.out.println("执行close方法,释放资源");throw new Exception("释放资源异常");}
}

执行结果: 执行close方法,释放资源 捕获异常: try块异常 被忽略的异常: 释放资源异常

即,catch到的是try块中的异常,释放资源时产生的异常被忽略了。

2.3 实践中的问题

实际上,很多时候try块中的异常和close方法抛出的异常是同一类型的。比如流、网络等不论是try块还是close方法都是抛出IOException,我们该怎么办? 最佳实践:按异常栈最底层的方法名判断。如果是close方法抛出的异常,就是关闭资源时产生的。 注:我们的方法名不能叫close

public class TestTryWithResources {public static void main(String[] args) {try (MyResource resource = new MyResource()) {throw new Exception("try块异常");} catch (Exception e) {if(!"close".equals(e.getStackTrace()[0].getMethodName())){System.out.println("处理业务异常");}}}
}/*** 自定义一个资源类,close时抛出异常*/
class MyResource implements AutoCloseable {@Overridepublic void close() throws Exception {System.out.println("执行close方法,释放资源");throw new Exception("释放资源异常");}
}

转载于:https://my.oschina.net/u/145060/blog/701357

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458321.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

平板电脑离寿终正寝还有多远?

近期有评论称,因为大尺寸智能手机越来越普及,小尺寸平板正遭受着越来越严重的冲击,在这样的背景下,平板厂商也纷纷转攻超大尺寸平板市场,以此避开大尺寸智能手机的竞争,只是。这样的策略转变是否能扭转平板…

Swift 与 JSON 数据

转载自: http://www.cnblogs.com/theswiftworld/p/4660177.html 我们大家平时在开发 App 的时候,相信接触最多的就是 JSON 数据了。只要你的 App 有读取网络数据的功能,你就免不了要与 JSON 打交道。比如你做一个新闻 App,你要读取…

TeamViewer - 最好用强大的免费跨平台远程桌面控制软件 (支持电脑和手机)

from:很早以前 LYcHEE 就提到过,家中的潮人爷爷奶奶每天摆弄着电脑,看看新闻发发邮件,安享晚年生活。只是意料之中的,电脑上莫名出现各种问题?不翼而飞的图标?照片又忘记怎么导出了?…

【设计模式】7、桥接模式

桥接模式就是对一个类的方法进行抽象化,吧不相关的因素提取出来,发展出第二个类 1 package com.shejimoshi.structural.Bridge;2 3 4 /**5 * 功能:桥接模式使用6 * 意图:将抽象部分与它的实现部分分离,使他们都…

TeamViewer免费版和付费版有什么不同

提到远程控制软件 TeamViewer无疑是目前业内知名度比较高的一款,所以说到远程控制软件可能大部分人首先想到的就是TeamViewer。在使用功能上,它支持远程桌面控制、文件传输、远程计算机锁定、视频会话、主控方和被控方身份互换,远程管理无人执…

【代码笔记】iOS-翻书效果的实现

代码: RootViewController.m #import "RootViewController.h"interface RootViewController ()endimplementation RootViewController- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {self [super initWithNibName:…

Halcon—Tuple中符号的含义

2014年08月08日 21:20:30阅读数:5429实例一(3d_coordinates.hdev):for I : 1 to NumImages by 1read_image (Image, calib/calib-3d-coord-I$02d)——C:\Program Files\MVTec\HALCON-10.0\images\的calib文件夹中开头是calib-3d-c…

Halcon学习笔记(三)---数据类型

Halcon学习笔记(三)---数据类型halcon只能在单独行进行注释,不能在语句后面进行注释。1、tuple(元组,重数)赋值符号“:”tuple算子:(1)变量定义与加减乘除运算代码如下:*…

论文笔记之:RATM: RECURRENT ATTENTIVE TRACKING MODEL

RATM: RECURRENT ATTENTIVE TRACKING MODEL ICLR 2016 本文主要内容是 结合 RNN 和 attention model 用来做目标跟踪。 其中模型的组成主要是: 1. an attention model 主要用来从输入图像中提取 patch; 2. RNN 用来预测 attention 参数,即&am…

【分享】WeX5的正确打开方式(5)——绑定机制

今天继续WeX5的绑定机制。 需求分析 记账本要实现的效果就是可以展示所有账单,还能实时动态编辑每一笔账单,官方案例的效果图如下: 展示页: 编辑页 个人觉得官方案例加入了许多元素,不熟悉的同学每一个点都很难理解&am…

关于未捕获异常的处理(WPF)

转载自:http://www.cnblogs.com/chenxizhang/p/3280947.html 这一篇文章来谈谈对于WPF应用程序开发中的未捕获异常的处理。 首先,我们当然是要求应用程序开发人员,尽可能地在程序可能出现异常的地方都去捕捉异常,使用try…catch的…

设计模式--23、访问者模式

访问者模式是一种较为复杂的行为型设计模式,它包含访问者和被访问元素两个主要组成部分,这些被访问的元素通常具有不同的类型,且不同的访问者可以对它们进行不同的访问操作。例如处方单中的各种药品信息就是被访问的元素,而划价人…

『协议』XML-RPC 协议规格说明

为什么80%的码农都做不了架构师?>>> 这篇文章提供所有实现XML-RPC协议所需要的内容。 一览 XML-RPC是一个工作在因特网上的远端程序调用(Remote Procedure Calling)协议。 XML-RPC消息是一个HTTP-POST请求(Request&…

Qt之QLineEdit详解(附源码)

原博客地址:http://blog.csdn.net/liang19890820/article/details/52044639,感谢原作者总结和分享。 简述 QLineEdit是一个单行文本输入框。 QLineEdit允许用户输入和编辑单行纯文本,提供了很多有用的编辑功能,包括:撤…

C#json数据的序列化和反序列化(将数据转换为对象或对象集合)

引用 System.Runtime.Serialization.Json 转载于:https://www.cnblogs.com/a849788087/p/5645828.html

位图(bmp)文件格式分析

from:https://blog.csdn.net/qingchuwudi/article/details/25785307 位图(bmp)文件格式分析 作者:深蓝(由博主分享) 一、什么是位图 计算机能以位图和矢量图格式显示图像。 1、位图(Bitmap): 图像又称点阵图或光…

java 基本功 —— 内存相关

2019独角兽企业重金招聘Python工程师标准>>> 首先我们来说说内存,因为从内存的角度来出发来分析一些变量,引用或者对象的生命周期会更好理解一些。 java是一门编程语言,他跟C有什么不同呢?本质上,他们都是一…

DOM事件处理有三个阶段

DOM事件处理有三个阶段: 捕捉阶段(capture phase):从最上层元素,直到最下层(你点击的那个target)元素。路过的所有节点都可以捕捉到该事件。命中阶段(target phase)&…

客户端程序自动更新(升级)的方式

from:https://blog.csdn.net/woaitingting1985/article/details/72954652一、C/S自动更新原理C/S程序自动升级是一个很重要的功能,原理其实很简单,一般包含两个程序一个是主程序,也就是除了升级功能以外的程序,另一个就…

怎么用源程序把ChemDraw结构复制到Word文档

在学习化学过程中,不可避免的会接触到各种化学结构。这个时候就需要通过绘制化学结构来进行这方面的学习和传播。ChemDraw Professional 15就可以辅助完成这方面的工作。很多的用户朋友会通过选中后复制粘贴可以将ChemDraw结构复制到Word文档中,但这只是…