2012-04-13 11 views
2

私は何かを明確にしたいと思います。Guava Reflectionを使用したプライベートフィールドへの参照

「プレーン」なJavaのリフレクション技術(ライブラリを使用しない)afaikではプライベートフィールドへの参照を取得することはできません。つまり、フィールド値はjava.lang.reflect.Fieldオブジェクトです。例えば

、私はこのクラスがある場合:私はこれを実行しようとすると

public class MyClass { 
    private String field1; 
} 

を:

Field field = MyClass.class.getField("field1"); 

私はNoSuchFieldException例外が発生します、予想通り。 Guava Reflection library

私はこれを実行しようとした場合、:

java.lang.IllegalStateException: Unknown property: field1 in class MyClass 

そして、これも期待された:

Object o = new MyClass(); 
Property property = Properties.getPropertyByName(o, "field1"); 
Field f = property.getField(); 

を私は次の例外を取得します。しかし、ゲッターメソッドを追加すると、次のようになります。

次に、Guava反射コードが機能しています。 私はこれについて少し損失があると告白する必要があります。リフレクションライブラリはゲッターを使ってプライベートインスタンス変数の値を返すことができますが、Fieldオブジェクト自体はゲッターが存在するだけなので、理解できますか?これはどうやって起こるのでしょうか?あなたはグアバは、ボンネットの下にやっていることはおそらくあり、標準のJavaリフレクションを使用して、プライベートフィールドに反映させることができ

+1

私は完全にはよく分からないが、あなたは 'フィールドフィールド= MyClassのを試してみました。 class.getDeclaredField( "field1"); '?これは違いかもしれません... – user219882

+0

はい、その唯一の問題は、getDeclaredFieldは私にクラスによって宣言されたフィールドだけを与え、祖先ではないということです。私は問題を回避する方法を見ていますが(祖先を通して反復する)、退屈な定型コードを書くのと少し似ています... – Sergio

+2

この質問はGuavaとは関係がないので、タグを付けない "Guava" –

答えて

3

Class<?> c = ... some class ... 
Field field = c.getDeclaredField("name"); 
field.setAccessible(true); 
Object value = field.get(object); 

getDeclaredFieldは、あなたがプライベートフィールドを取得することができます。セキュリティ上の問題を防ぐためには setAccessibleが必要です。

とにかく、ベストプラクティスとして、パブリックメンバーのみでリフレクションを使用することを検討してください。可能であればゲッター/セッターで作業してください。

希望に役立ちます。

+0

ありがとうございます、今は可能ですが、GuavaよりもFieldオブジェクトへのアクセスはゲッターの存在に依存しています。 – Sergio

+0

私はGuavaを自分で使っていませんが、これはおそらく起こりそうです:Javaでは、 "プロパティ"はアクセッサ/ミューテータのペア( "getName"と "setName")に基づくJavaBeanスタイルのプロパティを意味することがよくあります。 )。 "名前"という名前のプロパティを構築することで、GuavaはJavaBeanプロパティの規約に従って、フィールドではなくアクセサー/ミューテータだけを探している可能性があります。 – Torious

+0

私は、getDeclaredFieldの問題は、祖先クラスによって宣言されたフィールドには応答しないことに気がつきました。 – Sergio

1

FieldAccesibleObjectは、方法setAccessible()を持ち、プライベートフィールドの値にアクセスできるようにします。

グアバ-リフレクション(このライブラリは、グアバと区別されることに注意してください)Property.getFieldValueのような方法であなたのプライベートフィールドがアクセス可能に()

関連する問題