簡體   English   中英

使用反射在Java中獲取靜態私有哈希圖

[英]Using reflection get a static private hashmap in java

我正在嘗試找到一種通過Java從另一個類內的私有靜態字段中提取HashMap的方法。

例如。

在FooClass內部,有一個靜態字段,如下所示:

private Map entityRenderMap;

然后在其構造中具有:

entityRenderMap = new HashMap();

您如何通過Java中的Reflection獲取EntityRenderMap中的值? 我已經嘗試過了,但是出現錯誤:

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

您確定這是一個靜態字段嗎? get方法的javadoc明確指出:

如果基礎字段是靜態字段,則obj參數將被忽略; 它可以為空。

否則,基礎字段是實例字段。 如果指定的obj參數為null,則該方法將引發NullPointerException。 如果指定的對象不是聲明基礎字段的類或接口的實例,則該方法將引發IllegalArgumentException。

因此,對於靜態字段,由於將忽略該參數,因此不會獲得IllegalArgumentException 此外,您發布的代碼顯示它不是靜態字段,而是常規字段(因為它缺少單詞static ,並且在構造函數中對其進行了初始化)。

如果要訪問某個實例A的字段,則應將該實例A傳遞給Field#get方法,而不是A.field給您的cl.get(this.entityRenderMap)調用。

您可以看一下本教程的一些示例

如果該字段確實是靜態的,則應將null作為參數傳遞給cl.get()

如果該字段不是靜態的,那么必須傳遞FooClass實例,該實例要從以下位置獲取字段值:

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

首先,您的代碼與您的解釋不符。 它是真的是靜態字段還是不是(您的代碼說不是)?

如果它是靜態的,則應將null作為參數傳遞給cl.get() (不需要實例來訪問靜態成員)。

但是,我懷疑您的字段實際上不是靜態的,並且您將錯誤的實例傳遞給cl.get() JavaDocs將Field.get()聲明為在這種情況下將拋出IllegalArgumentException 您需要將RenderManager實例傳遞給此方法。 您的代碼看起來像是您傳遞了MapentityRenderMap )。

最后,此代碼是否在您的RenderManager類中? 我對此表示懷疑,因為您使用與this名稱相同的字段訪問您要設置的字段。 在這種情況下,根本不要使用反射!

我假設cljava.lang.reflect.Field 文檔指出,Fields的get方法將拋出:

IllegalArgumentException-如果指定的對象不是聲明基礎字段(或其子類或實現者)的類或接口的實例。

您應該將RenderManager -object傳遞給get方法而不是字段(除非它是靜態的,根據您的示例,這不是靜態的)。

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("");
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM