繁体   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