JDK7的嘗試關閉資源語法可套用的物件,必須實作java.lang.AutoCloseable
介面,這可以在API文件上得知:
AutoCloseable
是JDK7新增的介面,僅定義了close()
方法:package java.lang;
public interface AutoCloseable {
void close() throws Exception;
}
所有繼承
AutoCloseable
的子介面,或實作AutoCloseable
的類別,可在AutoCloseable
的API文件上查詢得知:只要實作
AutoCloseable
介面,就可以套用至嘗試關閉資源語法,以下是個簡單示範:package cc.openhome;
public class Main {
public static void main(String[] args) {
try(Resource res = new Resource()) {
res.doSome();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
class Resource implements AutoCloseable {
void doSome() {
System.out.println("作一些事");
}
@Override
public void close() throws Exception {
System.out.println("資源被關閉");
}
}
執行結果如下:
作一些事
資源被關閉
資源被關閉
嘗試關閉資源語法也可以同時關閉兩個以上的物件資源,只要中間以分號區隔。來看看以下的範例,哪個物件資源會先被關閉呢?
package cc.openhome;
public class Main2 {
public static void main(String[] args) {
try(ResourceSome some = new ResourceSome();
ResourceOther other = new ResourceOther()) {
some.doSome();
other.doOther();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
class ResourceSome implements AutoCloseable {
void doSome() {
System.out.println("作一些事");
}
@Override
public void close() throws Exception {
System.out.println("資源Some被關閉");
}
}
class ResourceOther implements AutoCloseable {
void doOther() {
System.out.println("作其它事");
}
@Override
public void close() throws Exception {
System.out.println("資源Other被關閉");
}
}
在
try
的括號中,越後面撰寫的物件資源會越早被關閉。執行結果如下,ResourceOther
實例會先被關閉,然後再關閉ResourceSome
實例:作一些事
作其它事
資源Other被關閉
資源Some被關閉
作其它事
資源Other被關閉
資源Some被關閉
可以實際觀察反組譯之後的程式碼,會發現每個
AutoCloseable
物件,都獨立使用一個try
、catch
、finally
,try
括號中越後面撰寫的物件,會是在越內層的try
、catch
、finally
中:...
try {
ResourceSome some = new ResourceSome();
Throwable localThrowable3 = null;
try {
ResourceOther other = new ResourceOther();
Throwable localThrowable4 = null;
try {
some.doSome();
other.doOther();
} catch (Throwable localThrowable1) {
localThrowable4 = localThrowable1;
throw localThrowable1;
} finally { // 處理ResourceOther的關閉
if (localThrowable4 != null) {
try {
other.close();
} catch (Throwable x2) {
localThrowable4.addSuppressed(x2);
}
} else {
other.close();
}
}
} catch (Throwable localThrowable2) {
localThrowable3 = localThrowable2;
throw localThrowable2;
} finally { // 處理ResourceSome的關閉
if (localThrowable3 != null) {
try {
some.close();
} catch (Throwable x2) {
localThrowable3.addSuppressed(x2);
}
} else {
some.close();
}
}
} catch (Exception ex) {
ex.printStackTrace();
}