2009-04-24 41 views
2

下面是我正在嘗試確定的...共享使用的靜態與實例方法

我有一個實用程序類將行添加到文本文件。 這個必須被其他一些類使用,比如 一個常見的日誌文件。

在我的第一個實現中,我想要使用它的所有類 創建一個無參考實例,例如,

new Logger(logline,logname);

構造函數創建一個PrintWriter,追加行 並關閉文件。

這看起來很浪費,因爲每個行都附加了一個新的實例,用於 。

另一種方法是在這個共同的類使用靜態方法,叫做「writeln」 ,因爲我的理解是靜態 方法和數據重複使用相同的內存超過&過......但

這個靜態方法創建了一個PrintWriter 的實例來完成它的工作,所以這並不意味着爲每一行創建了一個新的實例 ,如#1?

反正(我是比較新到Java)是否有 知名的,這樣做的批准方式,還是我們 只是創建了,並讓垃圾收集 後我們清理?

謝謝

回答

3

你不應該在你的構造函數中做任何工作。

構造函數用於對象設置。

您應該創建一個Log()方法來執行實際的日誌記錄。

Logger l = new Logger(); 
l.Log(logline,logname); 
l.Log(logline,logname); 

或者您可以將記錄儀設置爲Singleton。

Logger.getInstance().Log(logline, logname); 

Singleton模式在Java中: http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html

2

有幾種狀態,此對象可能要守住,尤其是PrintWriter的。如果您的Logger類將這些數據存儲爲實例數據,那麼執行日誌記錄的方法需要是實例方法,而不是靜態方法。因此,你需要從結構分離出記錄:

// Pass only the PrintWriter into the constructor, not the line to be logged. 
Logger myLogger = new Logger(filename); 

...

// Log a message 
myLogger.log("This is a message to be logged."); 

// Log another message, just for kicks. 
myLogger.log("this shows that myLogger can be used repeatedly."); 

我還沒有表現出任何的實現細節,但我希望這是足以讓你走。

5

明智的答案是,您應該使用「嚴重」的日誌記錄程序包,例如Commons Logging。但是,在這種情況下,您應該使用靜態方法(除非您想在代碼中維護日誌類實例,在這種情況下,您應該遵循本主題中的其他答案)。此外,您應該有一個靜態字段,初始化爲Map<String, PrintWriter>。 (您不必使用String作爲關鍵字:如果您需要有限數量的日誌記錄目標類型,請使用枚舉。)

然後,當您的方法看到映射中不存在的鍵時,當場創建PrintWriter,並將其粘貼在地圖上。您可能希望使用ConcurrentHashMap作爲支持映射類型,因此它是線程安全的。

您還需要提供關閉日誌記錄目標(也將清除地圖中的相關條目)的方法。

祝你好運!

+0

謝謝你,克里斯!這是與我最共鳴的 的建議。 有2個「日誌」文件 - 一個用於常規的 日誌記錄和一個用於錯誤 - 所以保持參考在 HashMap(一個調度表)是偉大的。關鍵可能是文件名。 有一件事我沒有抓到.. 關於關閉日誌目標...文件在每行之後關閉。 我是否也必須釋放內存?當JVM 退出時(在程序終止時),認爲這很好。 – javaphild 2009-04-24 19:06:49

+0

關閉每個日誌行的日誌記錄文件意味着您必須重新打開每個日誌行。這將是一個嚴重的性能問題。你應該考慮使用flush(),如果目標是確保日誌數據到達磁盤;這仍然帶來一些性能損失,但不是那麼多。 但是,如果你仍然堅持在每一行後關閉文件,那麼你不必擔心在其他地方關閉文件。是的,地圖可以自動釋放。 – 2009-04-25 01:37:33

+0

只要客戶端只通過字符串常量字段引用文件名,而不是直接字符串文字,就可以使用文件名作爲關鍵字。這減少了拼寫錯誤可能產生的影響,並且意味着您的文件名只能保存在一個地方,如果需要,可以很容易地進行更改。 – 2009-04-25 01:39:28

相關問題