Java 7和Java 8之间的细微自动关闭合同更改

Java 7的try-with-resources语句和与该语句一起使用的AutoCloseable类型的一个不错的功能是,静态代码分析工具可以检测到资源泄漏。 例如,Eclipse:

资源泄漏

具有以上配置并尝试运行以下程序时,您将收到三个警告:

public static void main(String[] args) 
throws Exception {Connection c = DriverManager.getConnection("jdbc:h2:~/test", "sa", "");Statement s = c.createStatement();ResultSet r = s.executeQuery("SELECT 1 + 1");r.next();System.out.println(r.getInt(1));
}

输出是琐碎的

2

警告会在所有csr上发出。 一种快速的解决方案(不要这样做!)是使用Eclipse特定的SuppressWarnings参数抑制警告:

@SuppressWarnings("resource")
public static void main(String[] args) 
throws Exception {...
}

毕竟,WeKnowWhatWeReDoing™,这只是一个简单的示例,对吧?

错误!

即使对于简单的示例(至少在Java 7之后),解决此问题的正确方法是使用轻松的try-with-resources语句。

public static void main(String[] args) 
throws Exception {try (Connection c = DriverManager.getConnection("jdbc:h2:~/test", "sa", "");Statement s = c.createStatement();ResultSet r = s.executeQuery("SELECT 1 + 1")) {r.next();System.out.println(r.getInt(1));}
}

实际上,如果Eclipse可以自动修复此警告并将所有单独的语句包装在try-with-resources语句中,那就太好了。 请支持此功能请求!

Java 8处理了什么?

在Java 8中, AutoCloseable上的合同已非常微妙地更改(或直率地更改了,具体取决于您的观点)。

Java 7版本

在不再需要时必须关闭的资源。

注意单词"must"

Java 8版本

在关闭之前可以保存资源(例如文件或套接字句柄)的对象。 退出在资源规范头中已声明该对象的try-with-resources块时,将自动调用AutoCloseable对象的close()方法。 这种构造可确保及时释放,避免资源耗尽异常和可能发生的错误。

API注意:

即使并非所有子类或实例都拥有可释放的资源,基类也有可能并且实际上是常见的。 对于必须完全通用的代码,或者已知AutoCloseable实例需要释放资源的代码,建议使用try-with-resources构造。 但是,当使用诸如Stream的功能同时支持基于I / O和基于非I / O的形式时,使用非基于I / O的形式时通常不需要使用资源尝试模块。

简而言之,从Java 8开始, AutoCloseable更具暗示性,表明您可能正在使用需要关闭的资源,但这并非一定如此。

这类似于Iterable契约,后者没有说明您只能对Iterable进行一次还是多次迭代,但是它强加了foreach循环所需的契约。

我们什么时候拥有“可选的可关闭”资源?

以jOOQ为例。 与JDBC不同,jOOQ 查询 ( 在jOOQ 3.7中被设置为AutoCloseable )可能表示资源,也可能不表示资源,这取决于您如何执行。 默认情况下,它不是资源:

try (Connection c = DriverManager.getConnection("jdbc:h2:~/test", "sa", "")) {// No new resources created here:ResultQuery<Record> query =DSL.using(c).resultQuery("SELECT 1 + 1");// Resources created and closed immediatelySystem.out.println(query.fetch());
}

输出再次是:

+----+
|   2|
+----+
|   2|
+----+

但是现在,我们再次在query变量上出现了Eclipse警告,说有一个资源需要关闭,即使通过这种方式使用jOOQ,我们知道事实并非如此。 上面的代码中唯一的资源是JDBC Connection ,并且已正确处理。 jOOQ内部的jOOQ PreparedStatementResultSet已完全处理,并急切地关闭了。

然后,为什么要首先实现AutoCloseable?

jOOQ与JDBC的默认行为相反。

  • 在JDBC中,默认情况下所有工作都是延迟进行的,并且必须显式关闭资源。
  • 在jOOQ中,默认情况下会急切地完成所有工作,并且可以有选择地使资源保持活动状态。

例如,以下代码将保持打开的PreparedStatementResultSet

try (Connection c = DriverManager.getConnection("jdbc:h2:~/test", "sa", "");// We "keep" the statement open in the ResultQueryResultQuery<Record> query =DSL.using(c).resultQuery("SELECT 1 + 1").keepStatement(true)) {// We keep the ResultSet open in the Cursortry (Cursor<Record> cursor = query.fetchLazy()) {System.out.println(cursor.fetchOne());}
}

在此版本中,我们在Eclipse中不再有任何警告,但是上述版本实际上是使用jOOQ API时的例外。

Java 8的Stream API也是如此。 有趣的是,Eclipse在这里不发出任何警告:

Stream<Integer> stream = Arrays.asList(1, 2, 3).stream();
stream.forEach(System.out::println);

结论

首先,资源泄漏检测似乎是一个不错的IDE /编译器功能。 但是,避免误报很难。 具体而言,因为Java 8改变了合同AutoCloseable ,实现者被允许执行AutoCloseable为一种方便的契约,而不是作为一种资源存在,必须关闭的清晰指示符。

这使IDE很难(甚至不是不可能)检测第三方合同(非JDK API)的资源泄漏,而这些合同通常并不为人所知。 与静态代码分析工具一样,该解决方案通常只是关闭潜在的资源泄漏检测:

资源泄漏解决方案

  • 有关更多的见解,另请参见Stuart Marks的Stack Overflow答案,该链接与EG关于lambda-dev的讨论相关联

翻译自: https://www.javacodegeeks.com/2015/12/subtle-autocloseable-contract-change-java-7-java-8.html

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

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

相关文章

reduce python3_更少循环?看看这3个Python函数

原标题&#xff1a;更少循环&#xff1f;看看这3个Python函数 全文共1146字&#xff0c;预计学习时长5分钟图源&#xff1a;wired 诞生于1991年的Python&#xff0c;这几年突然火了。简历上有了Python&#xff0c;就业竞争力瞬间提升&#xff0c;甚至一些小学教材上都出现了Pyt…

java图片上传(mvc)

最近有开始学起了java,好久没写文章了,好久没来博客园了。最近看了看博客园上次写的图片上传有很多人看&#xff0c;今天在一些篇关于java图片上传的。后台接收用的是mvc。不墨迹了&#xff0c;直接上图。 先看目录结构。idea开发。 一、图片上传还是使用的这款jq插件。前端部署…

appengine_Google AppEngine:任务队列API

appengine任务队列 com.google.appengine.api.taskqueue 使用任务队列&#xff0c;用户可以发起一个请求&#xff0c;以使应用程序执行此请求之外的工作。 它们是进行后台工作的强大工具。 此外&#xff0c;您可以将工作组织成小的离散单元&#xff08;任务&#xff09;。 然后…

Android studio Error occurred during initialization of VM 问题解决

最近开发导入其他Android项目遇见的问题,如下图&#xff1a; 解决办法&#xff1a; 将org.gradle.jvmargs的值该为521&#xff08;堆内存分配过高导致&#xff09; 备忘&#xff0c;希望能帮助到大家转载于:https://www.cnblogs.com/yunfang/p/6857096.html

滑动窗口限流 java_Spring Boot 的接口限流算法优缺点深度分析

点击上方蓝色字体&#xff0c;选择“标星公众号”优质文章&#xff0c;第一时间送达上一篇&#xff1a;这300G的Java资料是我师傅当年给我的&#xff0c;免费分享给大家(已修复)下一篇&#xff1a;昨天分享资料不小心把百度网盘深处的秘密泄露了(已修复)转自: loubobooo原文&am…

mips j指令_MIPS的基本实现

MIPS核心指令集&#xff1a;指令集概括为3个指令类&#xff1a;存储器访问指令类lw&#xff0c;sw等2. 算术逻辑指令类add&#xff0c;sub等3. 转移指令类beg&#xff0c;J等指令的共同性取指令&#xff0c;送PC值给Memory&#xff1b;根据指令内容读取寄存器内容&#xff1b;除…

腾讯管家去除桌面快捷小图标

找了大半天&#xff0c;原来腾讯管家也可以&#xff1a; 废话不多说&#xff0c;动手实践吧。。。。。 打开电脑管家——电脑诊所——桌面图标——【去掉快捷方式小箭头】 就这样轻松的实现了&#xff0c;赶快试试吧&#xff01; 转载于:https://www.cnblogs.com/yjq520/p/6858…

argparse模块_Argparse:一个具体案例教会你python命令行参数解析

问题描述&#xff1a;现有一个用于数据格式转换的py脚本(多转一)&#xff0c;执行时通过命令行传入一系列的参数控制其具体运行方式&#xff0c;使满足以下要求&#xff1a;1. 必须传入需要处理的原始数据文件名2. 可以指定输入文件的格式&#xff0c;若没有指定则使用默认值&a…

Eclipse中src/main/resources配置文件启动问题

项目pom文件有做修改如下的时候&#xff0c;还没有进行mvn clean install 启动test项目中的appcontext会 可以手动清空 然后就可以了。 出现如下问题的原因是 配置文件默认输出到target/classes 下 项目启动默认也会找该目录下的配置文件 其实这里pom文件拷贝配置文件只是用于读…

仍然不安全:变成了Java 9功能的Java 6中的主要错误

sun.misc.Unsafe的未来将如何发展&#xff1f; 随着2015年即将结束&#xff0c;我们认为这将是对Java社区过去一年中最热门辩论之一进行尸检的好机会。 通过查看标题&#xff0c;您中的大多数人可能已经开始在口腔中产生酸味并在肠道中产生愤怒的感觉&#xff0c;但是如果您错…

camvid数据集使用方法_使用PyTorch处理CIFAR10数据集并显示

在训练图像分类的时候&#xff0c;我们通常会使用CIFAR10数据集&#xff0c;今天就先写一下如何展示数据集的图片及预处理。第一部分代码&#xff0c;展示原始图像&#xff1a;import numpy as npimport torch#导入内置cifarfrom torchvision.datasets import cifar#预处理模块…

rhel 8.2不识别unicode_基于tensorflow 实现端到端的OCR:二代身份证号识别

最近在研究OCR识别相关的东西&#xff0c;最终目标是能识别身份证上的所有中文汉字数字&#xff0c;不过本文先设定一个小目标&#xff0c;先识别定长为18的身份证号&#xff0c;当然本文的思路也是可以复用来识别定长的验证码识别的。本文实现思路主要来源于Xlvector的博客&am…

Lua和C++交互详细总结

转载自&#xff1a;http://www.cnblogs.com/sevenyuan/p/4511808.html 一、Lua堆栈 要理解Lua和C交互&#xff0c;首先要理解Lua堆栈。 简单来说&#xff0c;Lua和C/C语言通信的主要方法是一个无处不在的虚拟栈。栈的特点是先进后出。 在Lua中&#xff0c;Lua堆栈就是一个struc…

adf开发_ADF BC:创建绑定到业务组件的UI表

adf开发在此示例中&#xff0c;我们将展示如何创建绑定到业务组件的简单UI表&#xff08;af&#xff1a;table&#xff09;。 我再次尝试使用简单的标准在网上进行搜索&#xff1a; “如何创建绑定到业务组件ADF 11g的af&#xff1a;table” 我必须承认我没有得到我想要的答案…

java游戏热血江湖,热血江湖源码_附安装教程

释放双眼&#xff0c;带上耳机&#xff0c;听听看~&#xff01;源码里面可能有联系方式之类的不要相信&#xff0c;反正我在这里已经说过了&#xff0c;你们上当就不管我的事了还有&#xff0c;源码里面的联系方式跟我没关系!教程来了认真看&#xff01;&#xff01;&#xff0…

在没有适当上下文的情况下引发异常是一种不良习惯

Allison Anders等人的《四个房间》&#xff08;1995&#xff09;。 我不断重复同样的错误。 因此&#xff0c;该停止并制定规则以防止这种情况了。 错误不是致命的&#xff0c;但很烦人。 当查看生产日志时&#xff0c;经常会看到类似"File doesnt exist" &#xff…

内存压力测试软件_日常游戏,毫无压力,荣耀Magicbook 14锐龙版性能测试

上期蚂蚁给大家带来了荣耀Magicbook 14锐龙版的初见评测&#xff0c;本期将会带来性能的测试&#xff0c;究竟这台高性价比的电脑&#xff0c;能不能应付得了日常的游戏使用呢&#xff1f;蚂蚁这次使用的测试软件分别为&#xff1a;鲁大师、CPU-Z、Cinebench R15、CrystalDiskM…

c 解析java byte,深入解析Java编程中面向字节流的一些应用

文件输入输出流文件输入输出流 FileInputStream 和 FileOutputStream 负责完成对本地磁盘文件的顺序输入输出操作。【例】通过程序创建一个文件&#xff0c;从键盘输入字符&#xff0c;当遇到字符“#”时结束&#xff0c;在屏幕上显示该文件的所有内容import java.io.*;class e…

cdatabase读取excel第一行数据_pandas读取excel数据并对重复数据进行标记或者删除

pandas读取excel数据并对重复数据进行标记或者删除​mp.weixin.qq.compandas通常在读取excel数据之后&#xff0c;如果需要进行去重&#xff0c;有两种方式&#xff0c;一种是进行标记&#xff0c;另一种是在pandas中直接去重如下图所示&#xff0c;excel数据&#xff1a;&…

java 7.函数-递归_带有谓词的Java中的函数样式-第2部分

java 7.函数-递归在本文的第一部分中&#xff0c;我们介绍了谓词&#xff0c;这些谓词通过具有返回true或false的单一方法的简单接口&#xff0c;为Java等面向对象的语言带来了函数式编程的某些好处。 在第二部分和最后一部分中&#xff0c;我们将介绍一些更高级的概念&#xf…