Javaの最適化スキルを向上させようとしています。それを達成するために、私は自分が作った古いプログラムを持っており、それを改善するために最善を尽くしています。このプログラムでは、ロギングにSL4Jを使用しています。ロガーを取得するには:
private static final Logger logger = LoggerFactory.getLogger(this.getClass().getName());
コードを書いた時点で、クラス名への参照をリファクタリングする可能性があるため、これが最良のオプションだと思いました。しかし、今はもうわからない...
private static final Logger logger = LoggerFactory.getLogger(ClassName.class);
反対側では、クラス名への参照を保持しますが、1つのメソッド呼び出しを削除します。これは、1つのクラスのパフォーマンスの大きな改善ではないかもしれませんが、多くのクラスがある場合、これは何かかもしれません。
だから私の質問は:
どのアプローチが良いですか?クラス名を使用するか、リフレクションを介して取得しますか?
賛否両論で答えを動機付けてください。ありがとうございました。
ここで私の意見を共有します。これは、パフォーマンスの観点から気にする必要はないということです。おそらくコードには、このことよりもはるかに最適化できる部分があります:)
さて、あなたの質問について。 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");
}
_
お役に立てれば
私が普段やっていることは
private static final Logger logger = LoggerFactory.getLogger(ClassName.class);
しかし、イディオム
protected final Logger log = LoggerFactory.getLogger(getClass());
同様に一般的です。 この質問では これらの規則に関する詳細情報を見つけることができます。
私は好む
Logger logger = LoggerFactory.getLogger(ClassName.class);
なぜなら
this.getClass()
クラスの子のいずれかによってオーバーライドでき、ログに子クラス名が表示されます。ログは実際には親クラスで実行されるため、混乱を招く場合があります
遅刻!
私は将来これを探しているようです。
Java 7のMethodHandlesクラスを使用して、コピー/貼り付けに適したLoggerインスタンスを作成する方法があります(これが何かを行う正当な理由になることはほとんどありません!)。
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
ロガーを宣言するたびにクラス名を書きたくない場合は、次のユーティリティメソッドを使用できます。
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();
このようなアプローチでは、ロガー宣言はすべてのクラスで常に同じです。