3 回答

TA貢獻1811條經(jīng)驗 獲得超6個贊
1) 上面的示例代碼情況(即資源初始化失?。┦欠癫粚儆谶@種情況..無論try語句是正常完成還是突然完成,資源都將被關(guān)閉。這是否僅適用于在 try with resources 語句中成功初始化的資源并且 try 塊中存在錯誤?
目前尚不清楚您所引用的“資源將被關(guān)閉,無論 try 語句是正常完成還是突然完成”。盡管如此,如果資源規(guī)范中的資源嘗試初始化引發(fā)異常,則不會,該資源不會關(guān)閉,因為它沒有初始化為非空值(您的第二個要點,它是 JLS 文本的摘錄) .
如果資源規(guī)范中有多個資源,那么有可能在其中之一的初始化拋出之前先初始化一些資源;在這種情況下,那些成功初始化為非空值的將被關(guān)閉。
2) 如果在初始化資源時拋出異常(如示例),則屬于初始化不成功的情況。在這種情況下,我們?nèi)绾斡龅?try-with-resources 語句中拋出異常的場景(基本上只能在初始化期間發(fā)生)?是關(guān)閉資源時拋出的異常嗎?
try-with-resources 語句是一個復合語句,包含從初始try
關(guān)鍵字到相關(guān)塊的所有內(nèi)容,并包括任何catch
and 和finally
子句。主要重點是在try
塊內(nèi)部拋出異常的情況下正確清理。規(guī)范中關(guān)于資源初始化期間發(fā)生異常情況的位可以理解為N -resource try-with-resources 語句和N 個嵌套的單資源 try-with-resources 語句之間的等效性。
注意,那就是,在JLS禮物翻譯一試,與資源語句為等效代碼使用傳統(tǒng)try
/ catch
/finally
和明確的資源閉合。如果您正在為 try-with-resources 的語義而苦苦掙扎,那將是一個值得考慮的好資源。

TA貢獻1865條經(jīng)驗 獲得超7個贊
1) 是的。如果資源初始化成功并且 try 塊有異常,則資源將被關(guān)閉,就像我們在 finally 塊中沒有 try with resource 一樣。
2)文檔說(很少修改):
沒有try with resource,如果在一個方法中,read()和close()(在finally塊中)都拋出異常,則該方法拋出finally塊中拋出的異常;從 try 塊拋出的異常被抑制。相比之下,使用try with resource,如果try塊和try-with-resources語句都拋出異常,則該方法拋出try塊拋出的異常;從 try-with-resources 塊拋出的異常被抑制。
正如您所提到的,第二點中 try-with-resource 的異常將來自關(guān)閉資源。

TA貢獻1868條經(jīng)驗 獲得超4個贊
在嘗試與-資源是在舊的語法和使用舊的語法,可以幫助你了解它寫它的語法糖:
這種例子:
try (AutoCloseable ac1 = ac1(); AutoCloseable ac2 = ac2()) {
ac2.doWhatever();
} catch (Exception e) {
fail(e);
}
改寫成這樣:
AutoCloseable ac1 = null;
try {
ac1 = ac1();
AutoCloseable ac2 = null;
try {
ac2 = ac2();
ac2.doWhatever();
} catch (Exception e) {
fail(e);
} finally {
if (ac2 != null) ac2.close();
}
} catch (Exception e) {
fail(e);
} finally {
if (ac1 != null) ac1.close();
}
編譯器可能會優(yōu)化代碼:
只能有一個 finally 塊,它可能會將兩者合并。
使用一些合成函數(shù)來處理相同的捕獲。
如果您有興趣,E. Mandrikov 的這個演示文稿解釋了編譯器的作用以及它如何成為代碼覆蓋率的難題。
如您所見,它可能在初始化部分失?。?/p>
ac1
初始化可能會失敗,在這種情況下,變量將是null
(默認值)。ac2
初始化可能會失敗,ac1
不會為空。ac1
并且ac2
可能工作,在這種情況下,只有doWhatever()
將負責失敗。
如果ac2
取決于ac1
,并且不在資源列表中,例如:
try (AutoCloseable ac2 = ac2(ac1())) { ...}
然后,AutoCloseable
構(gòu)建由ac1()
將不會關(guān)閉,除非它被關(guān)閉了ac2::close
。并且垃圾收集器不會調(diào)用ac1::close
.
添加回答
舉報