2012-01-22 17 views
1

私はJavaを介して別のクラス内のプライベート静的フィールドからHashMapを抽出する方法を見つけようとしています。リフレクションを使用してJavaで静的プライベートハッシュマップを取得

例えば、

インサイドFooClassこのようになります静的フィールドがあります:

private Map entityRenderMap; 

は、その構築物にそれはあります

あなたはリフレクション経由entityRenderMap内の値を取得するにはどうすればよい

entityRenderMap = new HashMap();

をJava?私はこれを試してみたが、エラーを取得:私が得る

cl = RenderManager.class.getDeclaredField("entityRenderMap"); 
     cl.setAccessible(true); 
     Object foo = cl.get(this.entityRenderMap); 
     Mod.log(cl.getName()); 

エラーは次のとおりです。

java.lang.IllegalArgumentException: Can not set java.util.Map field RenderManager.entityRenderMap to java.util.HashMap 
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source) 
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source) 
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(Unknown Source) 
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(Unknown Source 
+1

entityRenderMapは静的ではありません。 – simpatico

+0

フィールドは静的ですが、宣言はそれがそうではないことを示しています。 'cl.get()'に渡される 'this.entityRenderMap'の型は何ですか? –

+0

私はちょうどそのフィールドが静的ではないことに気付きました....私は完全にその豚をねじ込みました..(長い夜)。 –

答えて

2

まず、あなたのコードは、あなたの説明と一致していません。それは本当に静的なフィールドですか、そうではありませんか?

静的な場合は、nullを引数としてcl.get()に渡す必要があります(静的メンバーにアクセスするためのインスタンスは必要ありません)。

しかし、あなたのフィールドは実際には静的ではないと思われ、間違ったインスタンスをcl.get()に渡すと思われます。 JavaDocsをField.get()に設定すると、この場合はIllegalArgumentExceptionがスローされます。このメソッドにRenderManagerインスタンスを渡す必要があります。あなたのコードは、MapentityRenderMap)のようになります。

最後に、このコードはRenderManagerクラスの中にありますか?私はあなたが設定したいフィールドと同じ名前のthisでフィールドにアクセスしているので、これは疑わしい。この場合、反射をまったく使用しないでください!

+0

はい何故か何とかして、静かではありませんでした。(疲れたかもしれません)私は壁に頭を向けていました。それがソフトウェアではなく人間のバグであることを認識するためだけに:) –

2

は、あなたはそれが静的フィールドで特定されています。 getメソッドのjavadocには、明確に記載されています:

基本フィールドが静的フィールドの場合、obj引数は無視されます。 nullの可能性があります。

それ以外の場合は、基になるフィールドはインスタンスフィールドです。指定されたobj引数がnullの場合、このメソッドはNullPointerExceptionをスローします。指定されたオブジェクトが、基になるフィールドを宣言するクラスまたはインタフェースのインスタンスでない場合、メソッドはIllegalArgumentExceptionをスローします。

静的フィールドでは、パラメータが無視されるため、IllegalArgumentExceptionは取得できません。さらに、投稿したコードは静的なフィールドではなく通常のフィールドであることを示しています(単語staticがなく、コンストラクタで初期化されているため)。

あなたが特定のインスタンスAのフィールドにアクセスしたい場合は、あなたのcl.get(this.entityRenderMap)コールでやろうとしているとして、あなたはField#get方法、およびないA.fieldにそのインスタンスAを渡す必要があります。

あなたは、フィールドが実際に静的である場合、あなたはcl.get()の引数として渡す必要がありnullいくつかの例

2

ためthis tutorialを見てみることができます。

フィールドが静的でない場合、あなたはからフィールド値を取得したいFooClassのインスタンスを渡す必要があります。

FooClass fc = new FooClass(); // or whatever, provided that fc is a FooClass instance 
Object foo = cl.get(fc); 
1

私はcljava.lang.reflect.Fieldと仮定しています。 - 指定されたオブジェクトが基本となるフィールド(または サブクラスまたはそれらの実装)を宣言するクラスまたはインタフェースのインスタンス ない場合

、IllegalArgumentExceptionを:ドキュメントには、フィールドget-methodがスローされますと述べています。

フィールドの代わりにRenderManagerオブジェクトを取得メソッドに渡す必要があります(静的でない場合は、例によるものではありません)。

0
vim Test.java 
    import java.util.*; 
    import com.dp4j.*; 

class FooClass{ 

private static Map entityRenderMap; 

FooClass(){ 
entityRenderMap = new HashMap(); 
} 

} 

public class Test{ 
@Reflect 
public static void main(String... args){ 

Map reflectEntityMap = FooClass.entityRenderMap; 
} 
} 


javac -cp ~/ws/dp4j/dp4j.jar -Averbose=true Test.java 
Test.java:16: Note: 
import java.util.*; 
import com.dp4j.*; 

class FooClass { 
    private static Map entityRenderMap; 

    FooClass() { 
     entityRenderMap = new HashMap(); 
    } 
} 
public class Test { 

    public Test() { 
     super(); 
    } 

    @Reflect() 
    public static void main(String... args) throws java.lang.ClassNotFoundException, java.lang.NoSuchFieldException, java.lang.IllegalArgumentException, java.lang.IllegalAccessException { 
     java.lang.reflect.Field entityRenderMapField = null; 
     entityRenderMapField = Class.forName("FooClass").getDeclaredField("entityRenderMap"); 
     entityRenderMapField.setAccessible(true); 
     Map reflectEntityMap; 
     reflectEntityMap = (.java.util.Map)entityRenderMapField.get(""); 
    } 
} 
関連する問題