“嗨,阿米戈!”
“我只是決定和你討論一下finalize ()方法。”
“如果你還記得的話,finalize() 是一個特殊的方法,在垃圾收集器銷毀它之前由對象調用。”
“此方法的主要目的是通過關閉文件、I/O 流等來釋放已使用的外部非 Java 資源。”
“不幸的是,這個方法沒有達到我們的預期。Java 虛擬機可以推遲銷毀對象,也可以推遲調用 finalize 方法,只要它願意。而且,它不保證這個方法會被執行根本沒有被調用。有很多情況下它沒有被調用,都是以 «優化» 的名義。”
“我有兩個推薦信給你:”
Joshua Bloch 寫了一篇關於此方法的好文章:鏈接 我將轉述一小段摘錄:
|
如果我在採訪中說 finalize 是一個有害且危險的拐杖,其存在本身就令人困惑,我是對的嗎? |
“好吧,這讓我很高興,艾莉。”
“Java 7 有一個新語句來替換finalize方法。它稱為try-with-resources。它並不是finalize的真正替代品,而是一種替代方法。”
“它是不是像 try-catch,但有資源?”
“這幾乎就像try-catch。事情是,與finalize () 方法不同,try- catch-finally語句中的finally塊總是被執行。程序員在需要釋放資源時也使用了這種技術,關閉線程等。
“這是一個例子:”
InputStream is = null;
try
{
is = new FileInputStream("c:/file.txt");
is.read(…);
}
finally
{
if (is != null)
is.close();
}
“無論try塊是否正常執行或出現異常,finally塊都會被調用,並且有可能在那裡釋放佔用的資源。”
“因此,在 Java 7 中,決定將這種方法正式化,如下所示:”
try(InputStream is = new FileInputStream("c:/file.txt"))
{
is.read(…);
}
“這個特殊的try語句稱為try-with-resources(類似於集合如何為稱為foreach的替代方法)。”
“注意在try之後有括號,其中聲明變量和創建對象。這些對象可以在大括號指示的try塊內使用。當try塊執行完成時,無論它是正常結束還是在那裡是一個例外,將在括號內創建的任何對像上調用 close() 方法。”
“真有趣!這個符號比之前的符號要緊湊得多。我不確定我是否理解它。”
“沒你想的那麼難。”
“那麼,我可以在括號中指定每個對象的類別嗎?”
“是的,當然,否則括號就沒有什麼用了。”
“如果我需要在退出 try 塊後調用另一個方法,我應該把它放在哪裡?”
“這裡的事情有點微妙。Java 7 引入了以下接口:”
public interface AutoCloseable
{
void close() throws Exception;
}
“你的類可以實現這個接口。然後你可以在 try-with-resources 語句中使用它的對象。只有這樣的對象才能在 try-with-resources 語句的括號內創建,以實現 «automatic closure»。
“換句話說,我需要覆蓋 close 方法並在其中編寫代碼來 «clean up» 我的對象,我不能指定另一個方法嗎?”
“是的。但您可以指定多個對象——只需用分號分隔它們:”
try(
InputStream is = new FileInputStream("c:/file.txt");
OutputStream os = new FileOutputStream("c:/output.txt")
)
{
is.read(…);
os.write(…);
}
“那好多了,但沒有我希望的那麼酷。”
“沒那麼糟糕。你會習慣的。隨著時間的推移。”
GO TO FULL VERSION