5

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.

Community
  • 1
  • 1
Trent
  • 1,595
  • 15
  • 37

2 Answers2

6

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.

user2864740
  • 60,010
  • 15
  • 145
  • 220
  • @jahroy Perhaps. I'm reading it as the OP has no access to the *created* instance, hence the desire to "accessing local variables" - if the variable is accessible, then the object assigned to such is trivially obtained and the member field can be accessed by reflection. – user2864740 Jun 07 '14 at 06:55
  • That is most unfortunate as I have no control over A or B. That's OK, I was only trying to be evil/devious anyway. Thanks for the clear and concise answer. – Trent Jun 07 '14 at 06:58
-1

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.

  • Read the question -- "is it possible to access `instanceOfB` in order to access the value of `_nonStaticInt`". OP already knows how to get the variable. – awksp Jun 07 '14 at 07:28