2009-10-28 13 views
5

私は、(何らかの理由で)Javaのリフレクションを使って構築されたたくさんのクラスを持っているとします。今私は@PostInjectと注釈された であるフィールドに値をポスト注入する必要があります。Java:リフレクションを使用してフィールドを注入する最も速い方法は何ですか?

public class SomeClass { 
    @PostInject 
    private final String someString = null; 

    public void someMethod() { 
    // here, someString has a value. 
    } 
} 

私の質問は:リフレクションを使用してフィールドを設定するための高速な方法は何ですか?
多くのクラスで非常に頻繁に行う必要があることを覚えておいてください。つまり、パフォーマンスが適切な理由は です。

この擬似コードで示されている私は直感で行うだろう:

  • eachField.getAnnotation(PostInject.class);
  • @PostInject
    でアノテートされたクラス
    clazz.getFields();
  • チェックのすべてのフィールドを取得これらのフィールドにアクセスできるようにする。
    eachAnnotatedField.setAccessible(true);
  • 一定値
    eachAnnotatedField.set(clazz, someValue);

私はすべてのフィールドを取得することは行うには最も遅いものであることを恐れています。
フィールドを最初から知っている人はいますか?

注:クラスにメソッドを使用してフィールドを設定できるようにするインタフェースを実装することはできません。 私は POJOが必要です。

注2:ポストフィールド注入が必要な理由:APIユーザーの観点からは、最終フィールドを使用できる必要があります。さらに、APIによってフィールドの型および数が事前に分かっていない場合、インタフェースを使用してフィールドの初期化を行うことは不可能である。

NOTE2b:ユーザーの観点から、最終契約がない壊れています。それは最終的なままです。最初に、フィールドは初期化され、その後は変更できません。ところで、このコンセプトを使用する多くのAPIがありますが、その1つはJAXB(JDKの一部)です。

+0

私はあなたがこれをする必要がある理由について興味がありますか?この後ろに興味深い話がありますか?それがあれば、それを分かち合うことができますか? –

+0

私はJAXBと同様のマーシャラー| unmarshallerを書いていますが、もっと特殊な(したがって制限されています)。アノテーション付きPOJOは非常に柔軟性があります。 –

+1

実装者にアノテーションを使用する必要がある場合は、ここでインターフェイスを使用する以上のことは得られていないし、POJOを実際に使用しているわけでもありません - http://en.wikipedia.org/wiki/Plain_Old_Java_Object#Contextual_variations – Nate

答えて

7

オブジェクトを作成し、オブジェクト自体で取得した注釈付きフィールドのセットを保存した直後、または注釈付きフィールドのクラスマップの別のマップを保存すると、ステップ1〜3を実行しますか?その後

、あなたは、オブジェクト内の注入されたフィールドを更新オブジェクトまたは別々のマップのいずれかからセットを取得し、ステップ4

+0

完璧なアイデア! –

1

1を実行する必要があるとき、私はRSPのアイデアが好きです。


もう1つのオプションは、最初から関係するフィールドがいくつか分かっているので、それらのフィールドまたはメソッドのみを求めることです。

例:それは何か良いかどうか分からないのですかjava/lang/Class.html

1

getDeclaredMethodまたはgetDeclaredFieldを参照してください、それはあなたがやりたいのと同じようthis projectが見えます。引用:

反射ユーティリティおよびクラスとそのフィールドのJava 1.5とジェネリック医薬品との互換性 ある依存関係のない での作業 に関連 雑多なユーティリティのセット。高速動作のため

ユーティリティキャッシュ反射データ しかしは がオープンクラスローダーを保持し キャッシュは永久メモリ に存在させることを回避するために弱い/ソフトキャッシングを使用しています。 独自のキャッシングメカニズムを無効にする機能は、 です。

0

オブジェクト構築に依存関係を注入できる既存のフレームワークを利用することができます。たとえば、面接法を使用したSpring allows to do thatです。一般的な考え方は、春のレベルでBeanの依存関係を定義し、オブジェクトの作成を助言するためにターゲットクラスにマークを付けることです。実際の依存関係解決ロジックは、クラスのバイトコードに直接注入されます(コンパイル時またはロード時の織り方の使用が可能です)。

0

反射で何かをする最速の方法は、可能な限り、実際のReflection APIクラスをキャッシュすることです。

Object o = ... 
BeanPropertyController c = BeanPropertyController.of(o); 

for (String propertyName : c.getPropertyNames()) { 
     if (c.access(propertyName) == null && 
      c.typeOf(propertyName).equals(String.class)) { 
       c.mutate(propertyName, ""); 
     } 
} 

それが動作する方法は次のとおりです。たとえば、私は非常に最近、私は誰もが私はこれを行うことができますいくつかの点でやって終わるものの一つであると信じてまだ別のダイナミックPOJOマニピュレータを作りました基本的には、Beanのすべてのプロパティをlazyloadsして(注:いくつかの魔法が含まれている)、コントローラオブジェクトが実際に存在し、実際のコントローラオブジェクトが生きている限りそれらを再利用します。私が言うことができるのは、メソッドオブジェクトを保存するだけで、私はそのことをすごく速いものにすることができました。私はそれを非常に誇りに思っていますし、著作権などを整理することができると仮定しても解放することを検討します。

関連する問題