简体   繁体   中英

Using Java reflection to modify nesting class's fields from inner class

I'm experiencing odd behavior while debugging my Java reflection homework in Eclipse. I have 2 classes defined:

public class OuterClass{
    protected Person person;

    public void aPerson(Integer age) {
        person = new Person(age);
    }
}

public class OuterDerivedClass extends OuterClass {

    public class InnerClass extends OuterClass {

        public void aPerson(Integer age) {
            person = new Person(age);
        }
    }
}

At some point in my program, I instantiated an InnerClass instance like so (using reflection as my program is supposed to work on any class. Nested classes could be either static/non-static and public/private/protected):

Class<?> outer_class = outer_instance.getClass();
Constructor<?> ctor = inner_class.getDeclaredConstructor(outer_class);
Object inner_instance = ctor.newInstance(outer_instance);

Later on I invoked the OuterDerivedClass$InnerClass.aPerson method:

method.invoke(inner_instance, parameter);

For now, it seemed like all went OK: The inner_instance was created successfully, the correct aPerson method (the one in InnerClass) was invoked. BUT, later on my program, as I tried to access the person field from outer_instance, I figured out it was still NULL (though it was created in aPerson method). While debugging in Eclipse, I found out this:

在此处输入图片说明

(PersonStoryDerivedTest == OuterDerivedClass in my question).

The id of this$0 is the same as the one I sent to the constructor (outer_instance). I couldn't figure out what is the second person field (the one that apparently was created by invoking aPerson). Isn't this field supposed to exist only in the nesting class? My intention was that the invocation of OuterDerivedClass$InnerClass.aPerson would change the person field in outer_instance (I thought this is the reason why it was sent to the Constructor in the first place).

Can someone please clarify these issues? Thanks!

I couldn't figure out what is the second person field

Well, since

public class InnerClass extends OuterClass {
//                      ^^^^^^^^^^^^^^^^^^

your InnerClass also inherits its own person field which is set by

public void aPerson(Integer age) {
    person = new Person(age);
}

because person refers to this.person and this inside this method represents instance of class where method was implemented (in InnerClass).

If you want your method to initialize OuterClass#person field you need to refer to it via OuterDerivedClass.this.person , but this will leave uninitialized person field of InnerClass .

Other (simpler) option is not extending OuterClass from InnerClass :

public class InnerClass{

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM