finally的一个妙用
●传统用法
try-catch-finally大家都会用:try包裹可能抛出异常的代码;catch捕获异常并对其处理;finally做一些资源关闭等回收工作。简单明了一句话就能说清。
稍微进阶一些的,大家可能在笔试/面试/工作中遇到,如果try、catch中有了return,那finally的执行时在return之前还是return之后呢?我们查看java官方的说明可以得到答案:
If the try clause executes a return, the compiled code does the following:
Saves the return value (if any) in a local variable.
Executes a jsr to the code for the finally clause.
Upon return from the finally clause, returns the value saved in the local variable.
翻译一下:
如果try块中有return,代码会做以下工作:
1、将return的值保存在一个本地变量中;
2、执行finally块中的Java Specification Requests(jsr,java标准提案)代码;
3、执行完finally块后(从finally中返回后),return刚才保存在本地变量中的值。
解读一下,我们能从中得出以下结论:
1、try、catch和finally中都可以有return;
2、try或者catch(二者层次相同,正常逻辑与异常逻辑,因此可以如此推断,当然也可以验证)中return的值会先保存起来;
3、finally中执行完代码后(此处jsr笔者不是很理解,暂视为正常的java代码),无论对第2步中的返回值是否有修改,返回的均是第2步保存的内容。
●特殊妙用
根据前一部分的知识,我们可以进行如下的使用。结合这么一个需求:一个函数返回某个集合,并把该集合清空,以备其他操作该集合的对象能重新写入数据。一般业务场景可能是需要定期读取集合/内存/缓存中的数据,并把读过的数据删除,已防止集合/内存/缓存撑爆。
如果对finnaly不是很熟悉,可能会写出这样的代码:
public class Demo {
public static final List<String> stringList = new ArrayList<>();
public List<String> getAndClear(){
List<String> result = new ArrayList<>(stringList);
stringList.clear();
return result;
}
}
因为无法在return之后执行代码,因此考虑生成一个新的集合,把原集合清空,返回新集合。这么做不优雅之处在于手动实例化了一个新的对象。
但如果我们用finally来做,就不需要自己去实例化新对象了:
public class Demo {
public static final List<String> stringList = new ArrayList<>();
public List<String> getAndClear(){
try{
return stringList;
}
finally {
stringList.clear();
}
}
}
以上就是finnaly的一个妙用,主要是理解try-catch中用了return,代码的执行顺序已经数据变更。
finally的一个妙用的更多相关文章
- 使用val()另一个妙用------选中select/checkbox/radio的值
一直认为val()方法只有两个功能:1.能设置元素的值,2.获取元素的值.知道val()方法还有另外一个妙用,就是它能使select(下拉列表框).checkbox(多选框)和radio(单选框)相应 ...
- 关于Go语言,自己定义结构体标签的一个妙用.
在Go中首字母大写和小写,决定着这此变量能否被外部调用, 比如:在使用标准库的json编码自定一的结构的时候: <pre style="margin-top: 0px; margin- ...
- 使用docker 解决一个小问题,你也可能用的到
以前一直觉得docker是运维用的工具,或者devops 用的工具,一般人应该用不上,直到最近发现docker 还有另外一个妙用,不管是什么语言. 这几天开会网络特别不好,nodejs npm 仓库 ...
- C++11实现一个轻量级的AOP框架
AOP介绍 AOP(Aspect-Oriented Programming,面向方面编程),可以解决面向对象编程中的一些问题,是OOP的一种有益补充.面向对象编程中的继承是一种从上而下的关系,不适合定 ...
- [转]J-Link Commander的妙用
转自http://maker.zlgmcu.com/portal.php?mod=view&aid=3685 J-Link Commander作为J-Link驱动软件包的一个工具之一,为工程师 ...
- 学习 shell脚本之前的基础知识
转载自:http://www.92csz.com/study/linux/12.htm 学习 shell脚本之前的基础知识 日常的linux系统管理工作中必不可少的就是shell脚本,如果不会写sh ...
- Shell编程菜鸟基础入门笔记
Shell编程基础入门 1.shell格式:例 shell脚本开发习惯 1.指定解释器 #!/bin/bash 2.脚本开头加版权等信息如:#DATE:时间,#author(作者)#mail: ...
- CSS图片裁剪Clip
CSS Clip 裁剪 可以用它来裁剪一张图片噢. 我们来裁剪一下Google图标,把G字给裁剪下来. 注意这个clip得配合绝对定位才能使用,不然不起效果. rect (top, right, bo ...
- PowerShell脚本:随机密码生成器
脚本名称:s随机密码生成器_v2.63.ps1脚本作用:产生随机密码.每密码字符个数,密码数量,存盘位置等可以自定义.脚本用法:脚本采用了硬编码,所以你需要打开脚本,修改如下变量:$生成密码总个数 = ...
随机推荐
- 如果你的评论被WordPress的Akismet插件屏蔽,怎么解封?
Akismet是Matt Mullenweg早期创办的一个项目,现在已经是Automattic公司的一个专注于剿杀垃圾评论的产品.在Wordpress用户中使用最多,z-blog也有用户在用,由于垃圾 ...
- JS基础_if练习三
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- Java 实现 海康摄像头抓拍图像 Windows、Linux
先抱怨一下,打死都想不到,海康的摄像头SDK居然是一个Java类,还有必须的两个jar包(jna.jar,examples.jar).鬼能想得到会这么命名. 下面开始吧. Windows 把从官网下载 ...
- 分库分布的几件小事(四)分库分表的id主键生成
1.问题 其实这是分库分表之后你必然要面对的一个问题,就是id咋生成?因为要是分成多个表之后,每个表都是从1开始累加,那肯定不对啊,需要一个全局唯一的id来支持.所以这都是你实际生产环境中必须考虑的问 ...
- Cannot create OpenGL context for 'eglMakeCurrent'.
10.3.2编译的app,在小米手机上出这个问题,华为的正常. 解决方法: 窗口的Quality属性用SystemDefault,不要用HighQuality. 10.3.1也有此问题.
- 基于Scrapt框架的全站数据爬取
创建scrapy工程项目,除了爬虫文件中的代码需要略微修改,其他模块用法相同(如中间件,管道等): 爬虫文件代码流程 导入链接提取器 from scrapy.linkextractors import ...
- ElementUI Hello World
Vue Element UI Hello World <!DOCTYPE html> <html> <head> <meta charset="ut ...
- ubuntu版本信息查看
1.cat /etc/issue 2.cat /etc/lsb-release 3.uname -a 4.cat /proc/version 5.lsb_release -a 显卡信息1.lspci ...
- Hadoop_11_HDFS的流式 API 操作
对于MapReduce等框架来说,需要有一套更底层的API来获取某个指定文件中的一部分数据,而不是一整个文件 因此使用流的方式来操作 HDFS上的文件,可以实现读取指定偏移量范围的数据 1.客户端测试 ...
- 在STM32上如果不使用外部晶振,OSC_IN和OSC_OUT的接法
如果使用内部RC振荡器而不使用外部晶振,请按照下面方法处理: 1)对于100脚或144脚的产品,OSC_IN应接地,OSC_OUT应悬空.2)对于少于100脚的产品,有2种接法: 2.1)OSC_I ...