使用反射在java中获得一个静态私有哈希映射



我正试图找到一种方法,通过Java从另一个类中的私有静态字段中提取HashMap。

例如。

在FooClass中有一个静态字段,它看起来像这样:

private Map entityRenderMap;

然后在其结构中,它有:

entityRenderMap = new HashMap();

如何通过Java中的反射获取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

首先,您的代码与您的解释不匹配。它真的是一个静态字段吗?

如果它是静态的,您应该将null作为参数传递给cl.get()(您不需要实例来访问静态成员)。

但是,我怀疑您的字段实际上不是静态的,并且您将错误的实例传递给了cl.get()。到Field.get()的JavaDocs表示,在这种情况下,它将抛出一个IllegalArgumentException。您需要向该方法传递一个RenderManager实例。您的代码看起来像是传递了一个MapentityRenderMap)。

最后,这个代码在你的RenderManager类中吗?我怀疑这一点,因为您使用this访问与要设置的字段同名的字段。在这种情况下,根本不要使用反射!

您确定它是一个静态字段吗。get方法的javadoc明确指出:

如果基础字段是静态字段,则忽略obj参数;它可能是空的。

否则,基础字段为实例字段。如果指定的obj参数为null,则该方法将抛出NullPointerException。如果指定的对象不是声明底层字段的类或接口的实例,则该方法将抛出IllegalArgumentException。

因此,对于静态字段,您不会得到IllegalArgumentException,因为参数被忽略了。此外,您发布的代码显示它不是一个静态字段,而是一个常规字段(因为它缺少单词static,并且在构造函数中已初始化)。

如果您想访问某个实例A的字段,您应该将该实例A传递给Field#get方法,而不是像您试图使用cl.get(this.entityRenderMap)调用那样传递A.field

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

如果字段真的是静态的,那么应该将null作为参数传递给cl.get()

如果字段不是静态的,那么您必须传递FooClass的实例,您想从中获取字段值:

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

我假设cl是java.lang.reflect.Field。文档指出Fields的get方法将抛出:

IllegalArgumentException-如果指定的对象不是实例声明基础字段的类或接口(或其子类或实现者)。

您应该将RenderManager-对象传递给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("");
    }
}

相关内容

  • 没有找到相关文章

最新更新