首页 文章 精选 留言 我的

精选列表

搜索[企业微信汽车行业版],共10000篇文章
优秀的个人博客,低调大师

为什么effective java 第三版推荐使用try-with-resources代替try-finally

背景 try-finally 这个语句想必做java的同学都不陌生吧,每当我们有关闭资源的需求我们都会使用到try-finally这个语句,比如我们在使用锁的时候,无论是本地的可重入锁还是分布式锁都会有下面类似的结构代码,我们会在finally里面进行unlock,用于强制解锁: Lock lock = new ReentrantLock(); lock.lock(); try{ // doSometing }finally { lock.unlock(); } 或者我们使用java的文件流读取或者写入文件的时候,我们也会在finally中强制关闭文件流,防止资源泄漏。 InputStream inputStream = new FileInputStream("file"); try { System.out.println(inputStream.read(new byte[4])); }finally { inputStream.close(); } 其实乍一看 这样的写法应该没什么问题,但是如果我们出现了多个资源需要关闭我们应该怎么写呢?最常见的写法如下: InputStream inputStream = new FileInputStream("file"); OutputStream outStream = new FileOutputStream("file1"); try { System.out.println(inputStream.read(new byte[4])); outStream.write(new byte[4]); }finally { inputStream.close(); outStream.close(); } 我们在外面定义了两个资源,然后在finally里面依次对这两个资源进行关闭,这个写法在我最开始写java的时候对文件流和数据库连接池做close的时候一些教学的文章都是这么教学的,那么这个哪里有问题呢?问题其实在于如果在inputStream.close的时候抛出异常,那么outStream.close()就不会执行,这很明显不是我们想要的结果,所以后面就改成了下面这种多重嵌套的方式去写: InputStream inputStream = new FileInputStream("file"); try { System.out.println(inputStream.read(new byte[4])); try{ OutputStream outStream = new FileOutputStream("file1"); outStream.write(new byte[4]); }finally { outStream.close(); } }finally { inputStream.close(); } 在这种方式中即便是outStream.close()抛出了异常,但是我们依然会执行到inputStream.close(),因为他们是在不同的finally块,这个的确解决了我们的问题,但是还有两个问题没有解决: 带来的第一个问题就是如果我们有不止两个资源,比如有十个资源,难道需要让我们写十个嵌套的语句吗?写完之后这个代码还能看吗? 第二个问题就是如果我们在try里面出现异常,然后在finally里面又出现异常,就会导致异常覆盖,会导致finally里面的异常将try的异常覆盖了。 public class CloseTest { public void close(){ throw new RuntimeException("close"); } public static void main(String[] args) { CloseTest closeTest = new CloseTest(); try{ throw new RuntimeException("doSomething"); }finally { closeTest.close(); } } } 输出结果:Exception in thread "main" java.lang.RuntimeException: close 上面这个代码,我们期望的是能抛出doSomething的这个异常,但是实际的数据结果却是close的异常,这和我们的预期不符合。 try-with-resources 上面我们介绍了两个问题,于是在java7中引入了try-with-resources的语句,只要我们的资源实现了AutoCloseable这个接口那么我们就可以使用这个语句了,我们之前的文件流已经实现了这个接口那么我们可以直接使用: try(InputStream inputStream = new FileInputStream("file"); OutputStream outStream = new FileOutputStream("file1")) { System.out.println(inputStream.read(new byte[4])); outStream.write(new byte[4]); } 我们所有的资源定义全部都在try后面的括号中进行定义,通过这种方式我们就可以解决上面所说的几个问题: 首先第一个问题,我们通过这样的方式,代码非常整洁,无论你有多少个资源,都可以很简洁的去做。 第二个异常覆盖问题的话,我们可以通过实验来看一下,我们将代码改写为如下: public class CloseTest implements AutoCloseable { @Override public void close(){ System.out.println("close"); throw new RuntimeException("close"); } public static void main(String[] args) { try(CloseTest closeTest = new CloseTest(); CloseTest closeTest1 = new CloseTest();){ throw new RuntimeException("Something"); } } } 输出结果为: close close Exception in thread "main" java.lang.RuntimeException: Something at fudao.CloseTest.main(CloseTest.java:33) Suppressed: java.lang.RuntimeException: close at fudao.CloseTest.close(CloseTest.java:26) at fudao.CloseTest.main(CloseTest.java:34) Suppressed: java.lang.RuntimeException: close at fudao.CloseTest.close(CloseTest.java:26) at fudao.CloseTest.main(CloseTest.java:34) 我们在代码中定义了两个CloseTest,用来验证之前close出现异常是否会影响第二个,同时在close和try块里面都抛出不同的异常,可以看见我们的结果,输出了两个close,证明虽然close抛出异常,但是两个close都会执行。然后输出了doSomething的异常,可以发现这里我们输出的就是我们try块里面所抛出的异常,并且我们close的异常以Suppressed的方式记录在异常的堆栈里面,通过这样的方式我们两种异常都能记录下来。 try-with-resources原理 try-with-resources语句其实是一种语法糖,通过编译之后又回到了我们开始说的嵌套的那种模式: 可以发现try-with-resources被编译之后,又采取了嵌套的模式,但是和之前的嵌套有点不同,他close的时候都利用了catch去捕获了异常,然后添加到我们真正的异常中,整体逻辑比我们之前的嵌套要复杂一些。 总结 在我们关闭资源的时候,我们尽量优先推荐使用try-with-resources语句,但这里要注意的是很多资源其实是没有实现AutoCloseable接口的,比如我们最开始的Lock就没有实现这个接口,这个时候如果也想使用这种功能,可以采用组合的方式将Lock进行封装,来达到我们的目的。 如果大家觉得这篇文章对你有帮助,你的关注和转发是对我最大的支持,O(∩_∩)O:

优秀的个人博客,低调大师

极致查询性能 sqltoy-orm-4.12.8 发版增加对国产达梦数据库支持

更新内容 1、主要增加对国产达梦数据库的支持(目前除updateFetch:单次交互完成锁记录、修改、返回结果报游标错误外其他功能都通过测试) 2、修复因增加oceanBase方言导致sqlite方言未放入方言池中产生的bug 3、增加findEntity分页功能,便于单表查询直接可以链式代码中完成 4、优化Query()链式查询增加分页,同时将Page()链式分页代码标注为作废 5、优化一些注释和日志输出 开源地址: github:https://github.com/chenrenfei/sagacity-sqltoy gitee:https://gitee.com/sagacity/sagacity-sqltoy idea 插件(可在market直接检索sqltoy安装): https://gitee.com/threefish/sqltoy-idea-plugins sqltoy特点说明: 支持mysql、postgresql、db2、oracle、sqlserver、sqlite、clickhouse、elasticsearch、mongodb等 具有JPA模式的CRUD功能(即CRUD无需写sql),无需写Dao,sqltoy提供了SqlToyLazyDao,同时提供了quickvo从数据库生成POJO。 根本上杜绝了sql注入问题 最科学的sql编写方式 * sqltoy的sql编写(支持嵌套) select * from sqltoy_device_order_info t where #[t.ORDER_ID=:orderId] #[and t.ORGAN_ID in (:authedOrganIds)] #[and t.STAFF_ID in (:staffIds)] #[and t.TRANS_DATE>=:beginDate] #[and t.TRANS_DATE<:endDate] * mybatis同样功能实现 select * from sqltoy_device_order_info t <where> <if test="orderId!=null"> and t.ORDER_ID=#{orderId} </if> <if test="authedOrganIds!=null"> and t.ORGAN_ID in <foreach collection="authedOrganIds" item="order_id" separator="," open="(" close=")"> #{order_id} </foreach> </if> <if test="staffIds!=null"> and t.STAFF_ID in <foreach collection="staffIds" item="staff_id" separator="," open="(" close=")"> #{staff_id} </foreach> </if> <if test="beginDate!=null"> and t.TRANS_DATE>=#{beginDate} </if> <if test="endDate!=null"> and t.TRANS_DATE<#{endDate} </if> </where> 缓存翻译大幅提升性能,减少多表关联,让sql直观可维护 最高等级的分页优化 支持用算法代替sql实现行列转换、同比环比、分组汇总等 支持分库分表 sqltoy支持跨数据库函数自适应:一套sql可以自适应多种数据库 提供了5种默认的非数据库相关的主键策略 1、shortNanoTime 22位有序安全ID,格式: 13位当前毫秒+6位纳秒+3位主机ID 2、nanoTimeId 26位有序安全ID,格式:15位:yyMMddHHmmssSSS+6位纳秒+2位(线程Id+随机数)+3位主机ID 3、uuid:32 位uuid 4、SnowflakeId 雪花算法ID 5、redisId 基于redis 来产生规则的ID主键 提供了通用字段赋值处理 提供了树形表的统一处理机制 sql文件更新自动重载,便于开发阶段无需重启应用 慢sql统计功能 便于跟其他拓展平台集成,如报表平台、配置化服务平台 ```java public class SqlToyContext implements ApplicationContextAware { // 省略其他代码 /** * @todo 提供可以动态增加解析sql片段配置的接口,并返回具体id,用于第三方平台集成,如报表平台等 * @param sqlSegment * @return * @throws Exception */ public synchronized SqlToyConfig parseSqlSegment(Object sqlSegment) throws Exception { return scriptLoader.parseSqlSagment(sqlSegment); } } ```

优秀的个人博客,低调大师

PhpStorm 2020.1 稳定版发布:开箱即用的 composer.json 支持、改进的类型推断等

PhpStorm 正式发布了 2020.1 版本,主要包括开箱即用的 composer.json 支持、PCOV 和 PHPDBG 的代码覆盖、PHPUnit 工具箱、高级语法检查器以及许多其他更新内容。 开箱即用的 composer.json 支持 现在,在编辑 composer.json 文件时,所有依赖关系管理操作都可以直接使用。 可以从上下文菜单或按 Ctrl(⌘)+N 来创建新文件 composer.json。该文件的模板可以在 Preferences/Settings | Editor | File and Code Templates 中找到。 PHP 类型推断的改进 类型推断引擎是 PhpStorm 的核心,新版本对其进行了一些显著更改,包括: 高亮多余的 @var 标签 跟踪空类型 初始化数组的代码完成 array_map/filter 中的代码完成 PCOV 和 PHPDBG 的代码覆盖率 可以使用 Xdebug 获得代码覆盖率报告。但是由于它主要是调试器,因此开销很大。为了加快覆盖率的报告,你可以使用更加轻便的工具,例如 krakjoe/pcov 扩展或 PHP 5.6+ 内置的 PHPDBG。 现在,PhpStorm 两者都支持。用户需要为测试创建“运行”配置,在设置中选择所需的 Coverage 驱动程序,然后单击运行带有覆盖率报告的测试: PHPUnit 工具箱 在最近发布的 PHPUnit 9中,许多功能已被删除或已过时。为了加快迁移速度并防止错误,PhpStorm 添加了许多检查和快速修复。 另外,现在可以通过在类声明上调用 Alt(⌥)+Enter 选择“创建新的 PHP 测试”,从而快速地为该类创建新的测试。 新版本还包括在元数据、IDE、UI 等等各方面的改进,更新内容很多,详情可查看发布公告: https://blog.jetbrains.com/phpstorm/2020/04/phpstorm-2020-1-release/

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册