I'm trying to find a way to extract a HashMap from a private static field within another class via Java.
eg.
Inside FooClass there is a static field that looks like this:
private Map entityRenderMap;
Then in its construct it has:
entityRenderMap = new HashMap();
How do you get the values within entityRenderMap via Reflection in Java? I've tried this but get errors:
cl = RenderManager.class.getDeclaredField("entityRenderMap");
cl.setAccessible(true);
Object foo = cl.get(this.entityRenderMap);
Mod.log(cl.getName());
The error I get is:
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
Are you certain it is a static field. The javadoc of the get
method clearly states:
If the underlying field is a static field, the obj argument is ignored; it may be null.
Otherwise, the underlying field is an instance field. If the specified obj argument is null, the method throws a NullPointerException. If the specified object is not an instance of the class or interface declaring the underlying field, the method throws an IllegalArgumentException.
So with a static field you would not get the IllegalArgumentException
since the parameter is ignored. Further, the code you posted shows it is not a static field but a regular field (since it lacks the word static
, and its initialized in the constructor).
If you want to access the field of a certain instance A
, you should pass that instance A
to the Field#get
method, and not the A.field
as you are trying to do with your cl.get(this.entityRenderMap)
call.
You can take a look at this tutorial for some examples
If the field is really static, you should pass null
as an argument to cl.get()
.
If the field is not static, then you must pass the instance of FooClass
which you want to get the field value from:
FooClass fc = new FooClass(); // or whatever, provided that fc is a FooClass instance
Object foo = cl.get(fc);
First, your code doesn't match your explanation. Is it really a static field or is it not (your code says it's not)?
If it is static, you should pass null
as argument to cl.get()
(you don't need an instance to access static members).
However, I suspect that your field is actually not static, and your passing the wrong instance to cl.get()
. The JavaDocs to Field.get()
state it would throw an IllegalArgumentException
in this case. You need to pass a RenderManager
instance to this method. Your code looks like your passing a Map
(the entityRenderMap
).
And last, is this code inside your RenderManager
class? I suspect this, because your accessing a field with this
with the same name as the field you want to set. In this case, don't use reflection at all!
I'm assuming cl
is a java.lang.reflect.Field . The documentation states that Fields' get-method will throw:
IllegalArgumentException - if the specified object is not an instance of the class or interface declaring the underlying field (or a subclass or implementor thereof).
You should be passing the RenderManager
-object to the get-method instead of the field (unless it's static, which it is not according to your example).
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("");
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.