2016-10-04 6 views
0

リフレクションを使用して値を読み込んだ200個のフィールドを持つクラスが与えられました。それは私が反射点であると仮定し、これはフィールドのように扱いにくい量のために非常によく動作します。このリフレクションを使用せずにフィールドの値を取得する方法

for (Field f : this.getClass().getFields()) 
     { 
      try 
      { 
       Object o = f.get(this); 

       if (f.getType() == String.class) 
       { 
        //do things with the string 
       } 
      } 
      catch (Exception ex) 
      { 
       logger.error("Cannot get value for field. {}", ex.getMessage()); 
      } 

     } 

のように、基本的に見えます。私はそれが遅いので、それをリファクタリングするように求められました(それはありますか?)。

これまでの唯一の方法は、ハードなコーディングの不敬な点を思いついた唯一の方法ですが、別の簡単な方法がありますか?

+1

OPに作業コードがあり、リファクタを要求するため、この質問を議論の対象外としています。 [ask]を見て、[codereview.se]でこの質問をすることを検討してください。 – xenteros

+0

より良い、クラス全体を入れてください。 "遅い" - それはクラスの使用法と内容に依存します。個人的には、同じロジックを保存したい場合は、ここの反映が最良の解決策だと思います。これは抽象化の失敗(1つのクラスの中の200個のフィールドが混乱して処理され、!複数回フィルタリングされる必要がある)のように見えますが、深刻な実現の欠陥ではありません。 – Les

+0

それは遅いですか?教えてください。プロファイラをプログラムに配置し、このループで費やす時間を確認します。 –

答えて

4

まず、実際に遅いことをプロファイラーで確認する必要があります。反射は通常は変数にアクセスするよりも遅いですが、必ずしもそれが遅い原因であるとは限りません。

セッターを使用してこれらの値を変更している場合は、セッターが呼び出されるたびにMap<String,Object>を更新するようにクラスをリファクタリングすることができます。これにより、リフレクションよりもフィールドへのアクセスが速くなりますが、ユースケースによっては可能でない可能性があります。

+0

ああ、とてもいい。残念ながらフィールドは公開されており、直接設定されています。 – Nanor

+1

@Nanor一度のセッターは使えるだろう...! – Kayaman

3

ほとんどの場合、Fieldオブジェクトの取得に費やされます(フィルタリングされる可能性もあります)。実際のルックアップは非常に高速です。 ClassValueを使用してこの情報をキャッシュし、速度を上げます。これまでのところ

public enum StringFields { 
    INSTANCE; 

    final ClassValue<List<Field>> fieldsCache = new ClassValue<List<Field>>() { 
     @Override 
     protected List<Field> computeValue(Class<?> type) { 
      return Collections.unmodifiableList(
        Stream.of(type.getFields()) 
          .filter(f -> f.getType() == String.class) 
          .peek(f -> f.setAccessible(true)) // turn off security check 
          .collect(Collectors.toList())); 
     } 
    }; 

    public static List<Field> getAllStringFields(Class<?> type) { 
     return INSTANCE.fieldsCache.get(type); 
    } 
} 
+0

フィールドの名前を知っていれば、 'Object.get(String)'を行うことができました。 – Nanor

+0

@Nanor Fieldオブジェクトがキャッシュされていると、高速になります。例を追加しますが、忙しいです –

1

私はハードコーディングの彼の不信心な量を考え出すことができる唯一の方法は、別の迅速な方法はありますか?

リフレクションを使用して、これらのフィールドのゲッターを取得し、それらのゲッターを読み取るコードを生成できます。

コード生成は、ビルドステップの一部とすることができます。

関連する問題