web-dev-qa-db-ja.com

LoggerFactory.getLogger(ClassName.class)vs LoggerFactory.getLogger(this.getClass()。getName())

Javaの最適化スキルを向上させようとしています。それを達成するために、私は自分が作った古いプログラムを持っており、それを改善するために最善を尽くしています。このプログラムでは、ロギングにSL4Jを使用しています。ロガーを取得するには:

private static final Logger logger = LoggerFactory.getLogger(this.getClass().getName());

コードを書いた時点で、クラス名への参照をリファクタリングする可能性があるため、これが最良のオプションだと思いました。しかし、今はもうわからない...

private static final Logger logger = LoggerFactory.getLogger(ClassName.class);

反対側では、クラス名への参照を保持しますが、1つのメソッド呼び出しを削除します。これは、1つのクラスのパフォーマンスの大きな改善ではないかもしれませんが、多くのクラスがある場合、これは何かかもしれません。

だから私の質問は:

どのアプローチが良いですか?クラス名を使用するか、リフレクションを介して取得しますか?

賛否両論で答えを動機付けてください。ありがとうございました。

14
Aurasphere

ここで私の意見を共有します。これは、パフォーマンスの観点から気にする必要はないということです。おそらくコードには、このことよりもはるかに最適化できる部分があります:)

さて、あなたの質問について。 LoggerFactory's コードをご覧ください

getLogger(Class<?> name)はオーバーロードされたメソッドを呼び出すだけであることに注意してください。

_Logger logger = getLogger(clazz.getName());
_

そして、いくつかの追加の計算を行います。したがって、Stringを使用したメソッドは明らかにわずかに高速です。

一般に、パターンはLogger参照をクラスの静的フィールドとして維持することです。次のようなものです。

_public class SomeClass {
   private static final Logger LOG =   LoggerFactory.getLogger(SomeClass.class);
}
_

この場合、thisは実際には存在しない(静的コンテキストで実行している)ため、this.getClass()を実際に使用することはできません。

私の経験から、異なるクラスから同じロガーを本当に使用したい場合を除いて、ClassName.getClass()をパラメーターとして使用することをお勧めします。そのような場合、ロガーを示す論理定数を使用する方が適切です。

たとえば、3つの異なるクラスを使用してデータベースにアクセスしようとしているとします。したがって、ロガー「DB」を作成し、database.logに書き込むファイルアペンダーを割り当て、これら3つの異なるクラス間で同じロガーを再利用したいとします。

したがって、次のコードを使用する必要があります。

_public class SomeClass {
   private static final Logger LOG =   LoggerFactory.getLogger("DB");
}
_

お役に立てれば

10
Mark Bramnik

私が普段やっていることは

private static final Logger logger = LoggerFactory.getLogger(ClassName.class);

しかし、イディオム

protected final Logger log = LoggerFactory.getLogger(getClass());

同様に一般的です。 この質問では これらの規則に関する詳細情報を見つけることができます。

7

私は好む

Logger logger = LoggerFactory.getLogger(ClassName.class);

なぜなら

this.getClass() 

クラスの子のいずれかによってオーバーライドでき、ログに子クラス名が表示されます。ログは実際には親クラスで実行されるため、混乱を招く場合があります

5
D. Rakov

遅刻!

私は将来これを探しているようです。

Java 7のMethodHandlesクラスを使用して、コピー/貼り付けに適したLoggerインスタンスを作成する方法があります(これが何かを行う正当な理由になることはほとんどありません!)。

private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
4
Mark McLaren

ロガーを宣言するたびにクラス名を書きたくない場合は、次のユーティリティメソッドを使用できます。

    public static org.slf4j.Logger getLogger() {
        final Throwable t = new Throwable();
        t.fillInStackTrace();
        return LoggerFactory.getLogger(t.getStackTrace()[1].getClassName());
    }

この方法は次のように使用できます。

private static final Logger LOG = TheClassContainingTheMethod.getLogger();

このようなアプローチでは、ロガー宣言はすべてのクラスで常に同じです。

0
baronKarza