Just having a play around with Java reflection and I think I'm getting the hang of it for the most part. I understand from this question/answer that, for the most part, I'm limited to static variables. If I have an instance of the class though, I can access non-static variables, which does make sense, I get that much.
Say I have the following two classes:
public class A
{
private static int _staticInt;
public static void main(String[] args)
{
B instanceOfB = new B();
}
}
public class B
{
private int _nonStaticInt;
public Game() {}
}
I understand how to access _staticInt
, that's not an issue.
My understanding is that I can get the Field
for _nonStaticInt
in the same way (i.e. Field f = B.class.getDeclaredField("_nonStaticInt");
). From other research (javadocs, trails, etc) I have gathered that I need an instance of B
in order to get the value of _nonStaticInt
.
So my question; Since main
is static, is it possible to access instanceOfB
in order to access the value of _nonStaticInt
? I don't think it is possible, but I thought it's always best to consult people that are more knowledgable than myself before giving up on the idea.
Since main is static, is it possible to access instanceOfB in order to access the value of _nonStaticInt?
"No." Local variables (being in a static method or not) cannot be accessed with the Java Reflection API. Reflection only works at the type level, not the byte-code level2.
The stated understanding of the linked question is correct; reflection access of a non-static (instance) field logically requires an instance. That is, the issue then isn't about reflecting on the B type, the issue is about obtaining the B instance (which is assigned to a local variable) to reflect upon.
To do this the B instance has to be "bled" somehow - e.g. assigned to a static field or passed as an argument to a method/constructor from main1 - so that it can be used with reflection later as the object who's instance members are to be accessed.
The cleanest approach would probably be to pass the B instance down through the appropriate context (or "DI"), perhaps with the aide of IoC .. and maybe changing the type to avoid the use of reflection entirely.
1 Another possible way to "bleed" the B instance is to attach a debugger and inspect/use the local variable within the main methods executing frame - but this sounds like trying to swat a fly with a club.
2 Even tooling like BCEL/ASM wouldn't immediately help during the execution of the main method. Rather it would be used to deconstruct the method, add in the required hooks/code to "bleed" or use the instance created, and then construct a modified method to execute.
Yes, you can get the value of _nonStaticInt in that same way:
B instanceOfB = new B();
Field f = B.class.getDeclaredField("_nonStaticInt");
// Because the variable is private you need this:
f.setAccessible(true);
Object content = f.get(instanceOfB);
System.out.println(content);
The value will be 0, that is the default value for an int.