背景
在日常開發(fā)中,經(jīng)常都是手動(dòng)關(guān)閉資源刊橘,比如IO流鄙才,數(shù)據(jù)庫(kù)連接等。如果忘關(guān)了就可能造成嚴(yán)重的性能后果促绵。
try-finally帶來的問題
1攒庵、代碼不優(yōu)雅
手動(dòng)關(guān)閉IO流,特別是使用多個(gè)時(shí)败晴,finally方法里寫的嵌套代碼真的是不堪入目浓冒,下面看一個(gè)例子:
public static void main(String[] args) {
BufferedInputStream inputStream = null;
BufferedOutputStream outputStream = null;
try {
inputStream = new BufferedInputStream(new FileInputStream("t1.txt"));
outputStream = new BufferedOutputStream(new FileOutputStream("t2.txt"));
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
因?yàn)橐WCinputStream和outputStream都要正常關(guān)閉,所以往往會(huì)選擇嵌套著寫尖坤。
如果finally寫成下面那樣:
public static void main(String[] args) {
BufferedInputStream inputStream = null;
BufferedOutputStream outputStream = null;
try {
inputStream = new BufferedInputStream(new FileInputStream("t1.txt"));
outputStream = new BufferedOutputStream(new FileOutputStream("t2.txt"));
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
當(dāng)inputStream.close(); 出現(xiàn)異常了稳懒,就不會(huì)再運(yùn)行 outputStream.close();了,就會(huì)一直無法釋放資源慢味。
2场梆、異常屏蔽問題
當(dāng)我們想向上層throws異常時(shí),由于只能拋出一個(gè)異常纯路,所以下面例子中或油,inputStream的異常就被outStream屏蔽了。
控制臺(tái)只顯示outStream的異常:
活用try-with-resource
Java 7后引人 try-with-resources驰唬,幫助我們快速解決資源釋放顶岸。
上述代碼使用try-with-resource,是不是優(yōu)雅了很多=斜唷辖佣!
public static void main(String[] args) {
try (
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream("t1.txt"));
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream("t2.txt"));
) {
} catch (Exception e) {
e.printStackTrace();
}
}
其實(shí)try-with-resource的原理就是幫我們自動(dòng)補(bǔ)全close,下面是編譯后的class搓逾,和我們try-finally寫的是大同小異凌简。
public static void main(String[] args) {
try {
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream("t1.txt"));
try {
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream("t2.txt"));
outputStream.close();
} catch (Throwable var5) {
try {
inputStream.close();
} catch (Throwable var4) {
var5.addSuppressed(var4);
}
throw var5;
}
inputStream.close();
} catch (Exception var6) {
var6.printStackTrace();
}
}