我正试图找到一种方法,通过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
实例。您的代码看起来像是传递了一个Map
(entityRenderMap
)。
最后,这个代码在你的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("");
}
}