2009-04-24 7 views
2

ここに私が決定しようとしているのは...共用の静的メソッドとインスタンスメソッド

私は、テキストファイルに行を追加するユーティリティクラスを持っています。 共通のログファイルである のような他の多くのクラスで使用する必要があります。

私の最初の実装では、すべてのクラスがありました リファレンス不要のインスタンスを作成したいと思っていました。

new Logger(logline,logname);

コンストラクタはPrintWriterを作成し、ライン を追加し、ファイルを閉じます。

これは、すべての行が追加された の新しいインスタンスが作成されるため、無駄に思えました。

代替は、私は、静的 メソッドとデータがオーバー&上で同じメモリを再利用することを理解していたことから、この共通のクラスで「のwriteln」 という静的メソッドを、使用していた...しかし

この静的メソッドは、PrintWriter のインスタンスを作成してジョブを実行します。つまり、#1のように、すべての行に対してPrintWriterの新しいインスタンス が作成されるわけではありません。とにかく

、(私はJavaへの比較的新しいです)これを行うの よく知られ、承認された方法があるか、我々はわずかの距離の作成、およびガベージコレクタ は、私たちの後にクリーンアップしましょう のですか?

ありがとうございました

答えて

3

コンストラクタでは何もしないでください。

コンストラクタはオブジェクトセットアップのためのものです。

実際のログを行うには、Log()メソッドを作成する必要があります。

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

また、ロガーをシングルトンとして設定することもできます。 Javaで

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

Singletonパターン: 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つのログファイルがあります.1つは通常の ロギング用で、もう1つはエラー用です。したがって、 HashMap(ディスパッチテーブル)への参照を保持することは素晴らしいことです。キーはファイル名にすることができます。 私が捕まえなかったことの1つ。 ロギングターゲットのクローズについて...ファイルは各行の後で閉じられます。 メモリも解放する必要がありますか? JVM が終了すると(プログラム終了時に)これが起こったと思います。 – javaphild

+0

各ログ行のログファイルを閉じると、各ログ行に対して再度開く必要があります。これは重大なパフォーマンスヒットになるでしょう。ログデータがディスクにヒットすることを目的とする場合は、flush()を使用することを検討する必要があります。パフォーマンスペナルティはまだありますが、それほど多くはありません。 しかし、すべての行の後にファイルを閉じることを依頼している場合は、別の場所でファイルを閉じることについて心配する必要はありません。地図は自動的に解放されたままにすることができます。 –

+0

ファイル名をキーとして使用すると、クライアントが直接文字列リテラルではなく文字列定数フィールドのみを使用してファイル名を参照する限り、問題ありません。これにより、タイプミスの影響を減らすことができます。つまり、ファイル名が1か所に保存されているため、必要に応じて簡単に変更できます。 –