java自动生成合同_Java 7和Java 8之间的细微自动关闭合同更改
java自動(dòng)生成合同
Java 7的try-with-resources語(yǔ)句和與該語(yǔ)句一起使用的AutoCloseable類型的一個(gè)不錯(cuò)的功能是,靜態(tài)代碼分析工具可以檢測(cè)到資源泄漏。 例如,Eclipse:
當(dāng)您具有上述配置并嘗試運(yùn)行以下程序時(shí),您將收到三個(gè)警告:
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警告在所有c , s , r上發(fā)出。 一種快速的解決方法(不要這樣做!)是使用Eclipse特定的SuppressWarnings參數(shù)抑制警告:
@SuppressWarnings("resource") public static void main(String[] args) throws Exception {... }畢竟,WeKnowWhatWeReDoing?,這只是一個(gè)簡(jiǎn)單的示例,對(duì)吧?
錯(cuò)誤!
即使對(duì)于簡(jiǎn)單的示例(至少在Java 7之后),解決此問(wèn)題的正確方法是使用輕松的try-with-resources語(yǔ)句。
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));} }實(shí)際上,如果Eclipse可以自動(dòng)修復(fù)此警告并將所有單獨(dú)的語(yǔ)句包裝在try-with-resources語(yǔ)句中,那就太好了。 請(qǐng)支持此功能請(qǐng)求!
Java 8處理了什么?
在Java 8中, AutoCloseable上的約定已經(jīng)非常微妙地更改(或直率地更改了,具體取決于您的觀點(diǎn))。
Java 7版本
當(dāng)不再需要時(shí)必須關(guān)閉的資源。
注意單詞"must" 。
Java 8版本
在關(guān)閉之前可以保存資源(例如文件或套接字句柄)的對(duì)象。 當(dāng)退出在資源規(guī)范頭中已聲明該對(duì)象的try-with-resources塊時(shí),將自動(dòng)調(diào)用AutoCloseable對(duì)象的close()方法。 這種構(gòu)造可確保及時(shí)釋放,避免資源耗盡異常和可能發(fā)生的錯(cuò)誤。
API注意:
即使不是所有的子類或?qū)嵗紦碛锌舍尫诺馁Y源,基類也有可能并且實(shí)際上是常見(jiàn)的。 對(duì)于必須完全通用運(yùn)行的代碼,或者對(duì)于已知AutoCloseable實(shí)例需要釋放資源的代碼,建議使用try-with-resources構(gòu)造。 但是,當(dāng)使用諸如Stream的工具同時(shí)支持基于I / O和基于非I / O的形式時(shí),使用非基于I / O的形式時(shí)通常不需要使用資源嘗試塊。
簡(jiǎn)而言之,從Java 8開始, AutoCloseable更具暗示性,表明您可能正在使用需要關(guān)閉的資源,但這并非一定如此。
這類似于Iterable合同,后者沒(méi)有說(shuō)明您只能在Iterable進(jìn)行一次還是多次迭代,但是它強(qiáng)加了foreach循環(huán)所需的合同。
我們什么時(shí)候擁有“可選的可關(guān)閉”資源?
以jOOQ為例。 與JDBC不同,jOOQ 查詢 ( 在jOOQ 3.7中被設(shè)置為AutoCloseable )可能表示資源,也可能不表示資源,這取決于您如何執(zhí)行。 默認(rèn)情況下,它不是資源:
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| +----+但是現(xiàn)在,我們?cè)俅卧趒uery變量上出現(xiàn)了Eclipse警告,說(shuō)有一個(gè)資源需要關(guān)閉,即使通過(guò)這種方式使用jOOQ,我們知道事實(shí)并非如此。 上面的代碼中唯一的資源是JDBC Connection ,并且已正確處理。 jOOQ內(nèi)部的jOOQ PreparedStatement和ResultSet已完全處理,并急切地關(guān)閉了。
然后,為什么要首先實(shí)現(xiàn)AutoCloseable?
jOOQ與JDBC的默認(rèn)行為相反。
- 在JDBC中,默認(rèn)情況下所有工作都是延遲進(jìn)行的,并且必須顯式關(guān)閉資源。
- 在jOOQ中,默認(rèn)情況下會(huì)急切地完成所有工作,并且可以有選擇地使資源保持活動(dòng)狀態(tài)。
例如,以下代碼將保持打開的PreparedStatement和ResultSet :
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());} }在此版本中,我們?cè)贓clipse中不再有任何警告,但是上述版本實(shí)際上是使用jOOQ API時(shí)的例外。
Java 8的Stream API也是如此。 有趣的是,Eclipse在這里不發(fā)出任何警告:
Stream<Integer> stream = Arrays.asList(1, 2, 3).stream(); stream.forEach(System.out::println);結(jié)論
首先,資源泄漏檢測(cè)似乎是一個(gè)不錯(cuò)的IDE /編譯器功能。 但是,避免誤報(bào)很難。 具體而言,因?yàn)镴ava 8改變了合同AutoCloseable ,實(shí)現(xiàn)者被允許執(zhí)行AutoCloseable為一種方便的契約,而不是作為一種資源存在,必須關(guān)閉的清晰指示符。
這使IDE很難(甚至不是不可能)檢測(cè)第三方合同(非JDK API)的資源泄漏,而這些合同通常并不為人所知。 與靜態(tài)代碼分析工具一樣,該解決方案通常會(huì)關(guān)閉潛在的資源泄漏檢測(cè):
- 有關(guān)更多的見(jiàn)解,另請(qǐng)參見(jiàn)Stuart Marks的Stack Overflow答案,該鏈接與EG關(guān)于lambda-dev的討論相關(guān)聯(lián)
翻譯自: https://www.javacodegeeks.com/2015/12/subtle-autocloseable-contract-change-java-7-java-8.html
java自動(dòng)生成合同
總結(jié)
以上是生活随笔為你收集整理的java自动生成合同_Java 7和Java 8之间的细微自动关闭合同更改的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Excel 使用函数快速合并 1000
- 下一篇: facelets_Java EE 8中的