Java-try-with-resource
Java語言在發展至SE7時加進了try-with-resource的語法,只要「Resource」實作過java.lang.AutoCloseable這個介面,
在撰寫程式碼時可以讓整個例外處理的結構變得比較簡潔。
未使用try-with-resouce
1 2 3 4 5 6 7 8 9 10 11 12
| // resource 宣告 Resource res = null; try { res = new Resource(); // resource 初始化 // 其他處理 } catch (Exception ex) { // 例外處理 } finally { // resource 釋放或清除 }
|
使用try-with-resouce
1 2 3 4 5 6 7 8 9 10 11 12
| // 於 try 關鍵字後的小括號中進行 resource 宣告及初始化 try (Resource res = new Resource()) { // 其他處理 // 在 try 後方小括號初始化的資源會在離開 try 區塊時自動呼叫 close() } catch (Exception ex) { // 例外處理 }
不過上方結構有些限制,如果需要在catch區塊中存取Resource的變數的話, 只能回到之前不使用try-with-resouce的結構來進行,因為try-with-resource要求 需要被自動呼叫close方法的物件一定要在try後方的小括號中宣告及初始化,否則會引發編譯時期錯誤。
|
SE9使用try-with-resouce
1 2 3 4 5 6 7 8 9 10 11 12
| 在Java SE9之後針對這個限制進行了一些改變,允許開發者如同未使用try-with-resource一樣 在進入try區塊前先完成宣告及初始化,try之後的小括號中只要列出需要被自動呼叫close方法的變數即可。
// resource 宣告 Resource res = new Resource(); try (res) { // 其他處理 // 在 try 後方小括號的資源會在離開 try 區塊時自動呼叫 close() } catch (Exception ex) { // 例外處理 }
|
實際應用
1 2 3 4 5 6 7 8
| try (StringWriter out = new StringWriter(); JsonGenerator jGenerator = JSONUtils.getFactory().createGenerator(out)) { jGenerator.writeStartObject(); jGenerator.writeStringField("David", "Chen"); jGenerator.writeEndObject(); jGenerator.flush(); return out.toString(); }
|
結論
1 2
| 這邊要注意的是,不管是哪個版本的try-with-resource結構,其中的resource如果沒有宣告為final變數的話, 也都會被視作是「effectively final(等效final)變數」,也就是不能在其有效範圍中進行變數異動。
|