我有一些關於java定稿的問題。 例如,我有一個FileHelper類,並且此類與讀取文件,寫入文件等相關聯。 現在我的問題是,我有一個方法writeFile()在FileHelper類。現在如果我想關閉該文件 應該重寫finalize()方法並關閉文件,或者我可以關閉writeFile()方法內的文件本身?哪種方法是正確的?我已經將我的File變量聲明爲一個成員變量。如果重寫是一個糟糕的主意,那麼爲什麼我們要重寫finalize()方法?哪種情況?我讀過很多文章,他們說要關閉文件,字體等系統資源。java finalization疑惑
0
A
回答
3
最好的做法是儘快關閉文件。如果您有FileHelper靜態方法(假設你的助手是一堆靜態「幫手」的方法),我會關閉該文件內
static void writeFile(String fileName, String text) { // Exception
// Open file here
// write text
// close it
}
壓倒一切的finalize的目的是釋放例如在非託管資源以防萬一有人忘記這樣做。如果有人用你的助手這樣
FileHelper fileHelper = new FileHelper(file);
fileHelper.writeFile(text);
// forgot to fileHelper.close();
可以去覆蓋的最終化和調用close()時,GC運行裏面的文件將被關閉。問題:
- 正如我提到的早期版本的文件,應儘快關閉(但不是越快;))
- 這是不確定的(沒有身體知道什麼時候GC會開始)
- 這應該只用於以防止調用者忘記關閉文件的情況
0
重寫finalize()不是一個好習慣。我會在代碼中完成它。
1
在幾乎所有情況下使用終結器是一個壞主意。 Java規範聲明,不能保證終結器能夠運行。即使他們這樣做,你也無法控制何時會發生這種情況。
使用終結器作爲主要的關閉文件的機制總是一個壞主意。爲什麼?因爲如果GC長時間不運行,應用程序可能會耗盡文件描述符,並且文件打開嘗試將開始失敗。
處理打開的流的最好方法是將它們保存在本地變量和參數中,並使用try { ...} finally
來確保它們在完成時始終關閉。或者在Java 7中,使用新的「try with resource」語法。
如果您需要將流放入成員變量中,您可能應該讓父類實現一個關閉流的方法close()
,並使用try { ...} finally
來確保父類的實例關閉。
還應該指出的是,使用終結器來關閉「丟失」流是沒有意義的。使用外部資源需要關閉的流類已經具有完成此操作的終結器。
1
只有當Java垃圾收集器將要回收對象時,纔會調用finalize()方法。在finalize方法中釋放文件句柄是一個不好的做法。
它可能導致java.io.IOException:太多打開的文件,因爲無法保證垃圾回收器何時運行。
更好的選擇是關閉finally塊中的文件讀寫器對象。因爲它保證運行。
finally {
// Always close input and output streams. Doing this closes
// the channels associated with them as well.
try {
if (fin != null)
fin.close();
if (fout != null)
fout.close();
} catch (IOException e) {
}}
fin和fout是FileInputStream和FileOutputStream對象。
相關問題
- 1. Java String pool存儲疑惑
- 2. 疑惑
- 3. Threading android疑惑
- 4. Perl懷疑編碼疑惑
- 5. Subversion疑惑?
- 6. 疑惑 - matplotlib
- 7. NSnotifiaction疑惑
- 8. WordPress的疑惑
- 9. Oracle Schema疑惑?
- 10. 導航疑惑
- 11. NSUserDefaults疑惑
- 12. 圖形疑惑
- 13. dotnetnuke疑惑
- 14. UITableview疑惑
- 15. iphone webview疑惑
- 16. GL_EXT_direct_state_access疑惑
- 17. iphone/ipad疑惑
- 18. NSUserdefault疑惑
- 19. Java初學者在JDBC有些疑惑
- 20. 在Java中傳遞引用疑惑
- 21. C++到Java代碼轉換的疑惑
- 22. Java字符串池相關的疑惑
- 23. GCM執行疑惑
- 24. ipad分頁疑惑
- 25. 表查看疑惑
- 26. XML解析疑惑
- 27. 對Android的疑惑
- 28. ER Diagram Design疑惑
- 29. mailkit Sendmail的疑惑
- 30. WCF模仿疑惑
要添加一些顏色評論,覆蓋最終化也會使GC更昂貴(您的對象將通過至少兩次GC遍歷),並且JVM沒有義務以任何種類的及時方式調用該方法 - 甚至根本就不是。有關Finalize和GC的各種文章,所有這些強烈建議遠離重寫該方法。 – yshavit
當然,但這是一個角落案件。當我執行IO操作時,我不會擔心GC開銷 - 數量級降低。有點比較我的滾軸葉片和噴氣機。 –
毫無疑問,但我正在詳細闡述OP是否正在考慮在非IO類中使用該方法。想象一下,當我們談論這個問題時,我會提及它。 – yshavit