1

これは基本的な質問です。

メタデータ Bean で実行してはならないコードがあります。すべてのメタデータ Bean は、メタデータ パッケージの下にあります。

今、

リフレクション API を使用して、クラスがメタデータ パッケージにあるかどうかを調べます。

if (newEntity.getClass().getPackage().getName().contains("metadata")) 

この If は、このコード内のいくつかの場所で使用しています。

問題は次のとおりです。これを一度行う必要があります。

boolean isMetadata = false
if (newEntity.getClass().getPackage().getName().contains("metadata")) {
   isMetadata = true;
}

C++ は最適化を行い、このコードが既に呼び出されていることを認識し、再度呼び出すことはありません。JAVA は最適化を行いますか? 私はリフレクション API が非常に重いことを知っており、高価なランタイムを失いたくありません。

4

1 に答える 1

6

もちろん、最適化に取り組む前に、実際にパフォーマンスの問題があるかどうかを確認する必要があります。getClass()おそらくすでにかなり高速です(instanceofとにかく、より高速です)。パッケージ名をチェックし続ける必要がないように、メタデータ パッケージにある一連のクラスをキャッシュすることができます。

本当にパッケージを比較する必要がある場合は、一度Package.getPackage(String name)メソッドを使用してメタデータ パッケージを見つけてから、オブジェクトごとgetClass().getPackage()に前と同じように呼び出して、2 つのパッケージ オブジェクトを比較します。

==これは、パッケージ名の文字列をチェックするよりも迅速で洗練されていますが、複数のクラスローダーがある場合、Package オブジェクトが等しくなく ( )、Package がオーバーライドされないため、おそらく正しく機能しません.equals()。考えてみると、単一のクラスローダーで動作することさえ保証されていないかもしれませんが、実際には、別のコピーではなく同じ Package インスタンスを取得するのではないかと思います-これを最初に確認するのが賢明です!例えば:

String.class.getPackage() == Integer.class.getPackage() // should be true

のソースコードをチェックして更新するとClass.getPackage()、それらがオブジェクトをキャッシュしていることがわかるので、単一のクラスローダーを使用するときにそれらを安全に比較できるはずですPackage.getPackage()ClassLoader.getPackage()Package

パッケージの命名規則の問題点の 1 つは、コードベース全体でそれを強制および維持する必要があることです。これは、時間の経過とともに保守の問題になる可能性があります。クラスを識別するより明示的な方法の方がよい場合があります。

クラスの特定のグループを識別する代替アプローチには、次のものがあります。

  • メタデータ Bean にマーカー インターフェイスを実装させる
  • Java アノテーションを使用してメタデータ Bean をマークする
  • すべてのBeanに、定義した特定のカテゴリにあるかどうかを確認するために呼び出すことができるメソッドを使用して、共通のインターフェイスを実装させます。これは基本的に型システムを複製しているので醜いですが、リフレクションを必要としないので高速です。
于 2012-11-25T10:44:37.957 に答える