2012-12-12 17 views
14

Java7的嘗試,有資源,需要申報是偉大的,所有的,但我不能換我周圍爲什麼它需要包括在try聲明的資源的聲明頭。我的直覺說,下面應該是可能的:爲什麼在Java中的嘗試 - 以資源

CloseableResource thing; 
try (thing = methodThatCreatesAThingAndDoesSomeSideEffect()) { 
    // do some interesting things 
} 
thing.collectSomeStats(); 

唉,這將導致一個語法錯誤(若有所思地期待;)。移動類型定義/聲明到try聲明的作品,這當然移動的東西到相應範圍內。我可以找出如何解決這個當我想不是讓關越從我AutoClosable,我感興趣的是爲什麼編譯器需要像這樣。

+1

從Java 9開始,如果它是表示對最終或有效最終變量的引用的表達式就足夠了。 – aioobe

+0

JDK更新 - https://bugs.openjdk.java.net/browse/JDK-7196163 –

回答

7

您的版本沒有明確界定什麼應該被關閉,例如

CloseableResource thing; 
Parameter a; 

try (a = (thing = methodThatCreatesAThingAndDoesSomeSideEffect()).getParameter()) { 

,如果你還寫

try (12) { 

或東西做什麼?

ALSO

CloseableResource thing1 = methodThatCreatesAThingAndDoesSomeSideEffect(); 
CloseableResource thing2 = methodThatCreatesAThingAndDoesSomeSideEffect(); 

try(thing1) { 
} 

爲什麼只有接近thing1

所以當前的語法強迫你simultaneosly創建一個變量,打開關閉塊。

ALSO2

CloseableResource thing1 = methodThatCreatesAThingAndDoesSomeSideEffect();

try(thing1) { 
} 

thing1.doSomethingOnClosedResource(); 

因爲thing1依然存在。

+0

您的第一點是一個好的;離開這個宣言開闢了一個時髦的表達世界,這確實會在關閉什麼時產生很多模糊性。第二個是簡單的pebkac,Java試圖避免太多imho。但我想這只是個人喜好:) – akaIDIOT

+0

在第一個例子,一個是不關閉的,所以它不是一個真正的嘗試,有資源,第二個例子中,你會只開東西1,因此它只會密切thing1,唐「看不到與 –

+0

@Aviram一個問題,如果'A'是什麼'closeable'嗎? – Dims

2

閱讀中,我得出這一結論的Java規範(雖然它不是隱含指示的話):

他們讓你聲明的變量,並增加了一個隱含的決賽中以它來確保你可以不變量重新綁定的東西其他。

在這種情況下,就不可能關閉資源,因爲它不再綁定到該變量。

例如:

CloseableResource thing; 
try (thing = methodThatCreatesAThingAndDoesSomeSideEffect()) { 
    thing = null; 
    // thing can't be closed now 
} 

他們可以讓你使用最後如果外面我猜,但它是一種醜陋。


解決方法: 您可以使用finally如果你想進入申報資源:

try (CloseableResource thing = methodThatCreatesAThingAndDoesSomeSideEffect()) { 
    // do some interesting things 
} finally { 
    thing.collectSomeStats(); 
} 

牢記終於thing已經關閉

+0

不是一個真正的答案*爲什麼* -question,但仍然有效。 – akaIDIOT

+0

是的,我注意到,我提交了答案後,開始閱讀java lang規範,看他們是否解釋任何內容,但目前爲止沒有任何內容 –

+0

當我讀到隱式最後的結果時,我現在得到了一個理論 –

1

由於的Java 9可以聲明和初始化內部試穿與資源使用的塊以外的變量。變量的唯一附加要求是它必須是effectively final
所以現在是可以做到:

CloseableResource thing = methodThatCreatesAThingAndDoesSomeSideEffect(); 
try (thing) { 
    // do some interesting things 
} 
thing.collectSomeStats(); 

希望它能幫助。

相關問題